static int writeUTF(String 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.charAt(i);
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 = (DataOutputStream)out;
if(dos.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.charAt(i);
if (!((c >= 0x0001) && (c <= 0x007F))) break;
bytearr[count++] = (byte) c;
}
for (;i < strlen; i++){
c = str.charAt(i);
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.write(bytearr, 0, utflen+2);
// 写入的长度在字符串中增加了2,即字节长度标识所占用的资源
return utflen + 2;
}
DataInputStream
public final static String readUTF(DataInput in) throws IOException {
// 读取字符串字节长度
int utflen = in.readUnsignedShort();
//...
}
En fait, lors de l'appel à writeUTF pour écrire, jdk écrit en interne le nombre d'octets de la chaîne dans le flux. Lors de la lecture, la longueur de l'octet est d'abord lue, et la longueur de l'octet est lue en fonction de la valeur. longueur d'octet spécifiée la chaîne correspondante.
看源码,调用的第一句就获取了长度 int utflen = in.readUnsignedShort(); 这个方法的Doc :
Lit deux octets d'entrée et renvoie une valeur int comprise entre 0 et
Soit a le premier octet lu et b le deuxième octet. La valeur renvoyée est :
(((a & 0xff) << 8) | (b & 0xff)) Cette méthode est adaptée pour lire les octets écrits par la méthode writeShort de l'interface DataOutput si l'argument de writeShort était censé être une valeur comprise entre 0 et 65535. Renvoie : la valeur non signée de 16 bits lue. Lance : EOFException - si ce flux atteint la fin avant de lire tous les
IOException - si une erreur d'E/S se produit.
lireUTF的Doc:
Lit à partir du flux dans une représentation d'un caractère Unicode chaîne codée au format UTF-8 modifié ; cette chaîne de caractères est puis renvoyée sous forme de String. Les détails de la représentation UTF-8 modifiée sont exactement les mêmes que pour la méthode readUTF de DataInput.
DataOutputStream
DataInputStream
En fait, lors de l'appel à
writeUTF
pour écrire,jdk
écrit en interne le nombre d'octets de la chaîne dans le flux. Lors de la lecture, la longueur de l'octet est d'abord lue, et la longueur de l'octet est lue en fonction de la valeur. longueur d'octet spécifiée la chaîne correspondante.看源码,调用的第一句就获取了长度
int utflen = in.readUnsignedShort();
这个方法的Doc :
lireUTF的Doc: