Java 中的 DataInputStream 介绍_动力节点Java学院整理
DataInputStream介绍
DataInputStream是数据输入流。它继承于FilterInputStream。
DataInputStream是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型”。应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据。
DataInputStream函数列表
DataInputStream(InputStreamin) finalintread(byte[]buffer,intoffset,intlength) finalintread(byte[]buffer) finalbooleanreadBoolean() finalbytereadByte() finalcharreadChar() finaldoublereadDouble() finalfloatreadFloat() finalvoidreadFully(byte[]dst) finalvoidreadFully(byte[]dst,intoffset,intbyteCount) finalintreadInt() finalStringreadLine() finallongreadLong() finalshortreadShort() finalstaticStringreadUTF(DataInputin) finalStringreadUTF() finalintreadUnsignedByte() finalintreadUnsignedShort() finalintskipBytes(intcount)
DataInputStream.java源码分析(基于jdk1.7.40)
packagejava.io;
publicclassDataInputStreamextendsFilterInputStreamimplementsDataInput{
//构造函数。
publicDataInputStream(InputStreamin){
super(in);
}
privatebytebytearr[]=newbyte[80];
privatecharchararr[]=newchar[80];
//从“数据输入流”中读取一个字节
publicfinalintread(byteb[])throwsIOException{
returnin.read(b,0,b.length);
}
//从“数据输入流”中读取数据并存储到字节数组b中。
//off是字节数组b中开始存储元素的起始位置。
//len是读取字节的个数。
publicfinalintread(byteb[],intoff,intlen)throwsIOException{
returnin.read(b,off,len);
}
//从“数据输入流”中读取数据并填满字节数组b中;没有填满数组b则一直读取,直到填满位置。
//从字节数组b的位置0开始存储,并且读取的字节个数等于b的长度。
publicfinalvoidreadFully(byteb[])throwsIOException{
readFully(b,0,b.length);
}
//从“数据输入流”中读取数据并存储到字节数组b中;若没读取len个字节,直到一直读取直到读取完len个字节为止。
publicfinalvoidreadFully(byteb[],intoff,intlen)throwsIOException{
if(len<0)
thrownewIndexOutOfBoundsException();
intn=0;
while(n0)){
total+=cur;
}
returntotal;
}
//从“数据输入流”中读取boolean类型的值
publicfinalbooleanreadBoolean()throwsIOException{
intch=in.read();
if(ch<0)
thrownewEOFException();
return(ch!=0);
}
//从“数据输入流”中读取Byte类型的值
publicfinalbytereadByte()throwsIOException{
intch=in.read();
if(ch<0)
thrownewEOFException();
return(byte)(ch);
}
//从“数据输入流”中读取“无符号的Byte类型”的值,即读取值为正数的byte值
publicfinalintreadUnsignedByte()throwsIOException{
intch=in.read();
if(ch<0)
thrownewEOFException();
returnch;
}
//从“数据输入流”中读取“short类型”的值
publicfinalshortreadShort()throwsIOException{
intch=in.read();
intch=in.read();
if((ch1|ch2)<0)
thrownewEOFException();
return(short)((ch1<<8)+(ch2<<0));
}
//从“数据输入流”中读取“无符号的short类型”的值
publicfinalintreadUnsignedShort()throwsIOException{
intch1=in.read();
intch2=in.read();
if((ch1|ch2)<0)
thrownewEOFException();
return(ch1<<8)+(ch2<<0);
}
//从“数据输入流”中读取“char类型”的值
publicfinalcharreadChar()throwsIOException{
intch1=in.read();
intch2=in.read();
if((ch1|ch2)<0)
thrownewEOFException();
return(char)((ch1<<8)+(ch2<<0));
}
//从“数据输入流”中读取“int类型”的值
publicfinalintreadInt()throwsIOException{
intch1=in.read();
intch2=in.read();
intch3=in.read();
intch4=in.read();
if((ch1|ch2|ch3|ch4)<0)
thrownewEOFException();
return((ch1<<24)+(ch2<<16)+(ch3<<8)+(ch4<<0));
}
privatebytereadBuffer[]=newbyte[8];
//从“数据输入流”中读取“long类型”的值
publicfinallongreadLong()throwsIOException{
readFully(readBuffer,0,8);
return(((long)readBuffer[0]<<56)+
((long)(readBuffer[1]&255)<<48)+
((long)(readBuffer[2]&255)<<40)+
((long)(readBuffer[3]&255)<<32)+
((long)(readBuffer[4]&255)<<24)+
((readBuffer[5]&255)<<16)+
((readBuffer[6]&255)<<8)+
((readBuffer[7]&255)<<0));
}
//从“数据输入流”中读取“float类型”的值
publicfinalfloatreadFloat()throwsIOException{
returnFloat.intBitsToFloat(readInt());
}
//从“数据输入流”中读取“double类型”的值
publicfinaldoublereadDouble()throwsIOException{
returnDouble.longBitsToDouble(readLong());
}
privatecharlineBuffer[];
@Deprecated
publicfinalStringreadLine()throwsIOException{
charbuf[]=lineBuffer;
if(buf==null){
buf=lineBuffer=newchar[];
}
introom=buf.length;
intoffset=0;
intc;
loop:while(true){
switch(c=in.read()){
case-1:
case'\n':
breakloop;
case'\r':
intc2=in.read();
if((c2!='\n')&&(c2!=-1)){
if(!(ininstanceofPushbackInputStream)){
this.in=newPushbackInputStream(in);
}
((PushbackInputStream)in).unread(c2);
}
breakloop;
default:
if(--room<0){
buf=newchar[offset+128];
room=buf.length-offset-1;
System.arraycopy(lineBuffer,0,buf,0,offset);
lineBuffer=buf;
}
buf[offset++]=(char)c;
break;
}
}
if((c==-1)&&(offset==0)){
returnnull;
}
returnString.copyValueOf(buf,,offset);
}
//从“数据输入流”中读取“UTF类型”的值
publicfinalStringreadUTF()throwsIOException{
returnreadUTF(this);
}
publicfinalstaticStringreadUTF(DataInputin)throwsIOException{
//从“数据输入流”中读取“无符号的short类型”的值:
//注意:UTF-8输入流的前2个字节是数据的长度
intutflen=in.readUnsignedShort();
byte[]bytearr=null;
char[]chararr=null;
//如果in本身是“数据输入流”,
//则,设置字节数组bytearr="数据输入流"的成员bytearr
//设置字符数组chararr="数据输入流"的成员chararr
//否则的话,新建数组bytearr和chararr
if(ininstanceofDataInputStream){
DataInputStreamdis=(DataInputStream)in;
if(dis.bytearr.length127)break;
count++;
//将c保存到“字符数组chararr”中
chararr[chararr_count++]=(char)c;
}
//处理完输入流中单字节的符号之后,接下来我们继续处理。
while(count>4){
//若UTF-8是单字节,即bytearr[count]对应是“0xxxxxxx”形式;
//则bytearr[count]对应的int类型的c的取值范围是0-7。
case0:case1:case2:case3:case4:case5:case6:case7:
/*0xxxxxxx*/
count++;
chararr[chararr_count++]=(char)c;
break;
//若UTF-8是双字节,即bytearr[count]对应是“110xxxxx10xxxxxx”形式中的第一个,即“110xxxxx”
//则bytearr[count]对应的int类型的c的取值范围是12-13。
case12:case13:
/*110xxxxx10xxxxxx*/
count+=2;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-1];
if((char2&0xC0)!=0x80)
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
chararr[chararr_count++]=(char)(((c&0x1F)<<6)|
(char2&0x3F));
break;
//若UTF-8是三字节,即bytearr[count]对应是“1110xxxx10xxxxxx10xxxxxx”形式中的第一个,即“1110xxxx”
//则bytearr[count]对应的int类型的c的取值是14。
case14:
/*1110xxxx10xxxxxx10xxxxxx*/
count+=3;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-2];
char3=(int)bytearr[count-1];
if(((char2&0xC0)!=0x80)||((char3&0xC0)!=0x80))
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+(count-1));
chararr[chararr_count++]=(char)(((c&0x0F)<<12)|
((char2&0x3F)<<6)|
((char3&0x3F)<<0));
break;
//若UTF-8是四字节,即bytearr[count]对应是“11110xxx10xxxxxx10xxxxxx10xxxxxx”形式中的第一个,即“11110xxx”
//则bytearr[count]对应的int类型的c的取值是15
default:
/*10xxxxxx,1111xxxx*/
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
}
}
//Thenumberofcharsproducedmaybelessthanutflen
returnnewString(chararr,0,chararr_count);
}
}
说明:
DataInputStream的作用就是“允许应用程序以与机器无关方式从底层输入流中读取基本Java数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。”
DataInputStream中比较难以理解的函数就只有readUTF(DataInputin);下面,对这个函数进行详细的介绍,其它的函数请参考源码中的注释。
readUTF(DataInputin)源码如下:
publicfinalstaticStringreadUTF(DataInputin)throwsIOException{
//从“数据输入流”中读取“无符号的short类型”的值:
//注意:UTF-8输入流的前2个字节是数据的长度
intutflen=in.readUnsignedShort();
byte[]bytearr=null;
char[]chararr=null;
//如果in本身是“数据输入流”,
//则,设置字节数组bytearr="数据输入流"的成员bytearr
//设置字符数组chararr="数据输入流"的成员chararr
//否则的话,新建数组bytearr和chararr
if(ininstanceofDataInputStream){
DataInputStreamdis=(DataInputStream)in;
if(dis.bytearr.length127)break;
count++;
//将c保存到“字符数组chararr”中
chararr[chararr_count++]=(char)c;
}
//处理完输入流中单字节的符号之后,接下来我们继续处理。
while(count>4){
//若UTF-8是单字节,即bytearr[count]对应是“0xxxxxxx”形式;
//则bytearr[count]对应的int类型的c的取值范围是0-7。
case0:case1:case2:case3:case4:case5:case6:case7:
/*xxxxxxx*/
count++;
chararr[chararr_count++]=(char)c;
break;
//若UTF-8是双字节,即bytearr[count]对应是“110xxxxx10xxxxxx”形式中的第一个,即“110xxxxx”
//则bytearr[count]对应的int类型的c的取值范围是12-13。
case12:case13:
/*110xxxxx10xxxxxx*/
count+=2;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-1];
if((char2&0xC0)!=0x80)
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
chararr[chararr_count++]=(char)(((c&0x1F)<<6)|
(char2&0x3F));
break;
//若UTF-8是三字节,即bytearr[count]对应是“1110xxxx10xxxxxx10xxxxxx”形式中的第一个,即“1110xxxx”
//则bytearr[count]对应的int类型的c的取值是14。
case14:
/*1110xxxx10xxxxxx10xxxxxx*/
count+=3;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-2];
char3=(int)bytearr[count-1];
if(((char2&0xC0)!=0x80)||((char3&0xC0)!=0x80))
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+(count-1));
chararr[chararr_count++]=(char)(((c&0x0F)<<12)|
((char2&0x3F)<<6)|
((char3&0x3F)<<0));
break;
//若UTF-8是四字节,即bytearr[count]对应是“11110xxx10xxxxxx10xxxxxx10xxxxxx”形式中的第一个,即“11110xxx”
//则bytearr[count]对应的int类型的c的取值是
default:
/*10xxxxxx,1111xxxx*/
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
}
}
//Thenumberofcharsproducedmaybelessthanutflen
returnnewString(chararr,0,chararr_count);
}
说明:
(01)readUTF()的作用,是从输入流中读取UTF-8编码的数据,并以String字符串的形式返回。
(02)知道了readUTF()的作用之后,下面开始介绍readUTF()的流程:
第1步,读取出输入流中的UTF-8数据的长度。代码如下:
intutflen=in.readUnsignedShort();
UTF-8数据的长度包含在它的前两个字节当中;我们通过readUnsignedShort()读取出前两个字节对应的正整数就是UTF-8数据的长度。
第2步,创建2个数组:字节数组bytearr和字符数组chararr。代码如下:
if(ininstanceofDataInputStream){
DataInputStreamdis=(DataInputStream)in;
if(dis.bytearr.length
首先,判断该输入流本身是不是DataInputStream,即数据输入流;若是的话,
则,设置字节数组bytearr="数据输入流"的成员bytearr
设置字符数组chararr="数据输入流"的成员chararr
否则的话,新建数组bytearr和chararr。
第3步,将UTF-8数据全部读取到“字节数组bytearr”中。代码如下:
in.readFully(bytearr,0,utflen);
注意:这里是存储到字节数组,而不是字符数组!而且读取的是全部的数据。
第4步,对UTF-8中的单字节数据进行预处理。代码如下:
while(count127)break;
count++;
//将c保存到“字符数组chararr”中
chararr[chararr_count++]=(char)c;
}
UTF-8的数据是变长的,可以是1-4个字节;在readUTF()中,我们最终是将全部的UTF-8数据保存到“字符数组(而不是字节数组)”中,再将其转换为String字符串。
由于UTF-8的单字节和ASCII相同,所以这里就将它们进行预处理,直接保存到“字符数组chararr”中。对于其它的UTF-8数据,则在后面进行处理。
第5步,对“第4步预处理”之后的数据,接着进行处理。代码如下:
//处理完输入流中单字节的符号之后,接下来我们继续处理。
while(count>4){
//若UTF-8是单字节,即bytearr[count]对应是“0xxxxxxx”形式;
//则bytearr[count]对应的int类型的c的取值范围是0-7。
case0:case1:case2:case3:case4:case5:case6:case7:
/*0xxxxxxx*/
count++;
chararr[chararr_count++]=(char)c;
break;
//若UTF-8是双字节,即bytearr[count]对应是“110xxxxx10xxxxxx”形式中的第一个,即“110xxxxx”
//则bytearr[count]对应的int类型的c的取值范围是12-13。
case12:case13:
/*110xxxxx10xxxxxx*/
count+=2;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-1];
if((char2&0xC0)!=0x80)
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
chararr[chararr_count++]=(char)(((c&0x1F)<<6)|
(char2&0x3F));
break;
//若UTF-8是三字节,即bytearr[count]对应是“1110xxxx10xxxxxx10xxxxxx”形式中的第一个,即“1110xxxx”
//则bytearr[count]对应的int类型的c的取值是14。
case14:
/*1110xxxx10xxxxxx10xxxxxx*/
count+=3;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-2];
char3=(int)bytearr[count-1];
if(((char2&0xC0)!=0x80)||((char3&0xC0)!=0x80))
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+(count-1));
chararr[chararr_count++]=(char)(((c&0x0F)<<12)|
((char2&0x3F)<<6)|
((char3&0x3F)<<0));
break;
//若UTF-8是四字节,即bytearr[count]对应是“11110xxx10xxxxxx10xxxxxx10xxxxxx”形式中的第一个,即“11110xxx”
//则bytearr[count]对应的int类型的c的取值是15
default:
/*10xxxxxx,1111xxxx*/
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
}
}
(a)我们将下面的两条语句一起进行说明
c=(int)bytearr[count]&0xff;
switch(c>>4){...}
首先,我们必须要理解为什么要这么做(执行上面2条语句)呢?
原因很简单,这么做的目的就是为了区分UTF-8数据是几位的;因为UTF-8的数据是1~4字节不等。
我们先看看UTF-8在1~4位情况下的格式。
--------------------+---------------------------------------------
1字节UTF-8的通用格式 |0xxxxxxx
2字节UTF-8的通用格式 |110xxxxx10xxxxxx
3字节UTF-8的通用格式 |1110xxxx10xxxxxx10xxxxxx
4字节UTF-8的通用格式 |11110xxx10xxxxxx10xxxxxx10xxxxxx
执行c=(int)bytearr[count]&0xff;和c>>4这2项操作之后,上面的数据变成
--------------------+---------------------------------------------
1字节UTF-8的变换后对应的int类型值 |00000000000000000000000000000xxx (范围是0~7)
2字节UTF-8的变换后对应的int类型值 |0000000000000000000000000000110x (范围是12~13)
3字节UTF-8的变换后对应的int类型值 |00000000000000000000000000001110 (范围是14)
4字节UTF-8的变换后对应的int类型值 |00000000000000000000000000001111 (范围是15)
为什么会是这样呢?
我们以“2字节UTF-8的通用格式”来说明。
它的通用格式是“110xxxxx10xxxxxx”,我们在操作时,只会操作第1个字节,即只会操作“110xxxxx”
(a.1)在执行c=(int)bytearr[count]&0xff;时,首先将bytearr[count]转换成int。
“110xxxxx”
转成int类型之后,变成
“111111111111111111111111110xxxxx”
因为“110xxxxx”是负数(第1为是1),所以转换成int类型时多出来的位补1。
(a.2)接着c=(int)bytearr[count]&0xff;中,会将“转换成int类型后的bytearr[count]”与“0xff”进行逻辑与(即&)操作。结果如下:
“000000000000000000000000110xxxxx”
(a.3)执行c>>4时,会将上面的结果左移4位。得到的结果如下:
“0000000000000000000000000000110x”
(b)上面的理解之后,swicth(c>>4){...}其中的省略号部分就相当容易理解了。
我们还是以“2字节UTF-8的通用格式”来说明。
它会执行case12和case13;源码如下:
count+=2;
if(count>utflen)
thrownewUTFDataFormatException(
"malformedinput:partialcharacteratend");
char2=(int)bytearr[count-1];
if((char2&0xC0)!=0x80)
thrownewUTFDataFormatException(
"malformedinputaroundbyte"+count);
chararr[chararr_count++]=(char)(((c&0x1F)<<6)|(char2&0x3F));
(b.1)由于这种情况对应的UTF-8数据是“2字节”的,因此,执行count+2;直接跳过2个字节。
(b.2)由于chararr的元素是字符类型,而一个字符正好占2个字节;因为正好将(((c&0x1F)<<6)|(char2&0x3F));的结果转换成char,然后保存在chararr数组中。
第6步,将字符数组转换成String字符串,并返回。代码如下:
returnnewString(chararr,0,chararr_count);
示例代码
关于DataInputStream中API的详细用法,参考示例代码(DataInputStreamTest.java):
importjava.io.DataInputStream;
importjava.io.DataOutputStream;
importjava.io.ByteArrayInputStream;
importjava.io.File;
importjava.io.InputStream;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.FileNotFoundException;
importjava.lang.SecurityException;
/**
*DataInputStream和DataOutputStream测试程序
*
*
*/
publicclassDataInputStreamTest{
privatestaticfinalintLEN=5;
publicstaticvoidmain(String[]args){
//测试DataOutputStream,将数据写入到输出流中。
testDataOutputStream();
//测试DataInputStream,从上面的输出流结果中读取数据。
testDataInputStream();
}
/**
*DataOutputStream的API测试函数
*/
privatestaticvoidtestDataOutputStream(){
try{
Filefile=newFile("file.txt");
DataOutputStreamout=
newDataOutputStream(
newFileOutputStream(file));
out.writeBoolean(true);
out.writeByte((byte)0x41);
out.writeChar((char)0x4243);
out.writeShort((short)0x4445);
out.writeInt(0x12345678);
out.writeLong(0x0FEDCBA987654321L);
out.writeUTF("abcdefghijklmnopqrstuvwxyz严12");
out.close();
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
/**
*DataInputStream的API测试函数
*/
privatestaticvoidtestDataInputStream(){
try{
Filefile=newFile("file.txt");
DataInputStreamin=
newDataInputStream(
newFileInputStream(file));
System.out.printf("byteToHexString(0x8F):0x%s\n",byteToHexString((byte)0x8F));
System.out.printf("charToHexString(0x8FCF):0x%s\n",charToHexString((char)0x8FCF));
System.out.printf("readBoolean():%s\n",in.readBoolean());
System.out.printf("readByte():0x%s\n",byteToHexString(in.readByte()));
System.out.printf("readChar():0x%s\n",charToHexString(in.readChar()));
System.out.printf("readShort():0x%s\n",shortToHexString(in.readShort()));
System.out.printf("readInt():0x%s\n",Integer.toHexString(in.readInt()));
System.out.printf("readLong():0x%s\n",Long.toHexString(in.readLong()));
System.out.printf("readUTF():%s\n",in.readUTF());
in.close();
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
//打印byte对应的16进制的字符串
privatestaticStringbyteToHexString(byteval){
returnInteger.toHexString(val&xff);
}
//打印char对应的进制的字符串
privatestaticStringcharToHexString(charval){
returnInteger.toHexString(val);
}
//打印short对应的16进制的字符串
privatestaticStringshortToHexString(shortval){
returnInteger.toHexString(val&xffff);
}
}
运行结果:
byteToHexString(0x8F):0x8f
charToHexString(0x8FCF):0x8fcf
readBoolean():true
readByte():0x41
readChar():0x4243
readShort():0x4445
readInt():0x12345678
readLong():0xfedcba987654321
readUTF():abcdefghijklmnopqrstuvwxyz严12
结果说明:
(01)查看file.txt文本。16进制的数据显示如下:
001f对应的int值是31。它表示的含义是后面的UTF-8数据的长度。字符串“abcdefghijklmnopqrstuvwxyz严12”中字母“ab...xyz”的长度是26,“严”对应的UTF-8数据长度是3;“12”长度是2。总的长度=26+3+2=31。
(02)返回byte对应的16进制的字符串
源码如下:
privatestaticStringbyteToHexString(byteval){
returnInteger.toHexString(val&0xff);
}
想想为什么代码是:
returnInteger.toHexString(val&0xff);
而不是
returnInteger.toHexString(val);
我们先看看byteToHexString((byte)0x8F);在上面两种情况下的输出结果。
returnInteger.toHexString(val&0xff);对应的输出是“0xffffff8f”
returnInteger.toHexString(val);对应的输出是“0x8f”
为什么会这样呢?
原因其实很简单,就是“byte类型转换成int类型”导致的问题。
byte类型的0x8F是一个负数,它对应的2进制是10001111;将一个负数的byte转换成int类型时,执行的是有符号转型(新增位都填充符号位的数字)。0x8F的符号位是1,因为将它转换成int时,填充“1”;转型后的结果(2进制)是11111111111111111111111110001111,对应的16进制为0xffffff8f。
因为当我们执行Integer.toHexString(val);时,返回的就是0xffffff8f。
在Integer.toHexString(val&0xff)中,相当于0xffffff8f&0xff,得到的结果是0x8f。
(03)返回char和short对应的16进制的字符串
“返回char对应的16进制的字符串”对应的源码如下:
privatestaticStringcharToHexString(charval){
returnInteger.toHexString(val);
}
“返回short对应的16进制的字符串”对应源码如下:
privatestaticStringshortToHexString(shortval){
returnInteger.toHexString(val&0xffff);
}
比较上面的两个函数,为什么一个是“val”,而另一个是“val&0xffff”?
通过(02)的分析,我们类似的推出为什么“返回short对应的16进制的字符串”要执行“val&0xffff”。
但是,为什么“返回char对应的16进制的字符串”要执行“val”即可。原因也很简单,java中char是无符号类型,占两个字节。将char转换为int类型,执行的是无符号转型,新增为都填充0。
以上所述是小编给大家介绍的Java中的DataInputStream的相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!