(澳门正规博彩十大网站) Java的DataInputStream的readUTF方法是怎么读取字符串的???

大神们好,我是新手小白,今天在学习Java的IO操作中遇到一个百思不得其解的问题,下面的代码是今天做的关于DataInputStream类的练习,我很不解为什么DataInputStream的readUTF方法不需要任何参数,但是却在读取的时候可以知道自己读取多长,不明白他是怎么知道我当初在写入的时候写入的长度的,他是靠什么控制读取的范围的呀???比如下面的程序,readUTF方法就可以知道读取”昨天”这两个字,是怎么知道我就刚好需要读这两个字,而不会把下面的内容给读出。很是感谢大家的回答

package com.zhang.hello; import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; public class IODataStreamTest { public static void mainString[] args throws IOException { File file=new File"f:/zhang.dat"; if!file.exists{ file.createNewFile; } DataInputStream dis=new DataInputStreamnew FileInputStreamfile; DataOutputStream dos=new DataOutputStreamnew FileOutputStreamfile; int testInt=2016; double testDouble=10.12; long testLong=20161012; dos.writeInttestInt; dos.writeDoubletestDouble; dos.writeLongtestLong; //utf-8 一个中文占3个字节 dos.writeUTF"昨天"; dos.writeUTF"今天是个好日子"; dos.close; int testRInt=dis.readInt; System.out.printlntestRInt; double testRDouble=dis.readDouble; System.out.printlntestRDouble; long testRLong=dis.readLong; System.out.printlntestRLong; String testRStr=dis.readUTF;//为什么readUTF知道读取多长 System.out.printlntestRStr; dis.close; }
}

执行结果:
2016
10.12
20161012
昨天

DataOutputStream

static int writeUTFString str, DataOutput out throws IOException { int strlen = str.length; int utflen = 0; int c, count = 0; /* use charAt instead of copying String to char array */ for int i = 0; i < strlen; i++ { c = str.charAti; if c >= 0x0001 && c <= 0x007F { utflen++; } else if c > 0x07FF { utflen += 3; } else { utflen += 2; } } if utflen > 65535 throw new UTFDataFormatException "encoded string too long: " + utflen + " bytes"; byte[] bytearr = null; if out instanceof DataOutputStream { DataOutputStream dos = DataOutputStreamout; ifdos.bytearr == null || dos.bytearr.length < utflen+2 dos.bytearr = new byte[utflen*2 + 2]; bytearr = dos.bytearr; } else { bytearr = new byte[utflen+2]; } // 将字符串的字节长度写入流中 bytearr[count++] = byte utflen >>> 8 & 0xFF; bytearr[count++] = byte utflen >>> 0 & 0xFF; int i=0; for i=0; i<strlen; i++ { c = str.charAti; if !c >= 0x0001 && c <= 0x007F break; bytearr[count++] = byte c; } for ;i < strlen; i++{ c = str.charAti; if c >= 0x0001 && c <= 0x007F { bytearr[count++] = byte c; } else if c > 0x07FF { bytearr[count++] = byte 0xE0 | c >> 12 & 0x0F; bytearr[count++] = byte 0x80 | c >> 6 & 0x3F; bytearr[count++] = byte 0x80 | c >> 0 & 0x3F; } else { bytearr[count++] = byte 0xC0 | c >> 6 & 0x1F; bytearr[count++] = byte 0x80 | c >> 0 & 0x3F; } } out.writebytearr, 0, utflen+2; // 写入的长度在字符串中增加了2,即字节长度标识所占用的资源 return utflen + 2;
}

DataInputStream

public final static String readUTFDataInput in throws IOException { // 读取字符串字节长度 int utflen = in.readUnsignedShort; //...
}

实际上在调用writeUTF写入时jdk内部有将字符串的字节数写入流中,读取时先读取到字节长度,按照指定的字节长度读取出相应的字符串。

看源码,调用的第一句就获取了长度
int utflen = in.readUnsignedShort;
这个方法的Doc :

Reads two input bytes and returns an int value in the range 0 through

  1. Let a be the first byte read and b be the second byte. The value returned is:

a & 0xff << 8 | b & 0xff This method is suitable for reading
the bytes written by the writeShort method of interface DataOutput if
the argument to writeShort was intended to be a value in the range 0
through 65535. Returns: the unsigned 16-bit value read. Throws:
EOFException – if this stream reaches the end before reading all the

  1. IOException – if an I/O error occurs.

readUTF的Doc:

Reads from the stream in a representation of a Unicode character
string encoded in modified UTF-8 format; this string of characters is
then returned as a String. The details of the modified UTF-8
representation are exactly the same as for the readUTF method of
DataInput.

发表评论

电子邮件地址不会被公开。 必填项已用*标注