Java的DataInputStream和DataOutputStream数据输入输出流

时间:2021-05-20

DataInputStream
DataInputStream 是数据输入流。它继承于FilterInputStream。
DataInputStream 是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。应用程序可以使用DataOutputStream(数据输出流)写入由DataInputStream(数据输入流)读取的数据。
DataInputStream 函数列表:

DataInputStream(InputStream in)final int read(byte[] buffer, int offset, int length)final int read(byte[] buffer)final boolean readBoolean()final byte readByte()final char readChar()final double readDouble()final float readFloat()final void readFully(byte[] dst)final void readFully(byte[] dst, int offset, int byteCount)final int readInt()final String readLine()final long readLong()final short readShort()final static String readUTF(DataInput in)final String readUTF()final int readUnsignedByte()final int readUnsignedShort()final int skipBytes(int count)

示例代码:
关于DataInputStream中API的详细用法:

import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.ByteArrayInputStream;import java.io.File;import java.io.InputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.FileNotFoundException;import java.lang.SecurityException;/** * DataInputStream 和 DataOutputStream测试程序 * * @author skywang */public class DataInputStreamTest { private static final int LEN = 5; public static void main(String[] args) { // 测试DataOutputStream,将数据写入到输出流中。 testDataOutputStream() ; // 测试DataInputStream,从上面的输出流结果中读取数据。 testDataInputStream() ; } /** * DataOutputStream的API测试函数 */ private static void testDataOutputStream() { try { File file = new File("file.txt"); DataOutputStream out = new DataOutputStream( new FileOutputStream(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 (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * DataInputStream的API测试函数 */ private static void testDataInputStream() { try { File file = new File("file.txt"); DataInputStream in = new DataInputStream( new FileInputStream(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 (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 打印byte对应的16进制的字符串 private static String byteToHexString(byte val) { return Integer.toHexString(val & 0xff); } // 打印char对应的16进制的字符串 private static String charToHexString(char val) { return Integer.toHexString(val); } // 打印short对应的16进制的字符串 private static String shortToHexString(short val) { return Integer.toHexString(val & 0xffff); }}

运行结果:

byteToHexString(0x8F):0x8fcharToHexString(0x8FCF):0x8fcfreadBoolean():truereadByte():0x41readChar():0x4243readShort():0x4445readInt():0x12345678readLong():0xfedcba987654321readUTF():abcdefghijklmnopqrstuvwxyz严12

结果说明:
(1) 查看file.txt文本。16进制的数据显示如下:

001f 对应的int值是31。它表示的含义是后面的UTF-8数据的长度。字符串“abcdefghijklmnopqrstuvwxyz严12”中字母“ab...xyz”的长度是26,“严”对应的UTF-8数据长度是3;“12”长度是2。总的长度=26+3+2=31。
(2) 返回byte对应的16进制的字符串
源码如下:

private static String byteToHexString(byte val) { return Integer.toHexString(val & 0xff);}

想想为什么代码是:

return Integer.toHexString(val & 0xff);

而不是

return Integer.toHexString(val);

我们先看看 byteToHexString((byte)0x8F); 在上面两种情况下的输出结果。
return Integer.toHexString(val & 0xff); 对应的输出是“0xffffff8f”
return Integer.toHexString(val); 对应的输出是“0x8f”
为什么会这样呢?
原因其实很简单,就是“byte类型转换成int类型”导致的问题。
byte类型的0x8F是一个负数,它对应的2进制是10001111;将一个负数的byte转换成int类型时,执行的是有符号转型(新增位都填充符号位的数字)。0x8F的符号位是1,因为将它转换成int时,填充“1”;转型后的结果(2进制)是11111111 11111111 11111111 10001111,对应的16进制为0xffffff8f。
因为当我们执行Integer.toHexString(val);时,返回的就是0xffffff8f。
在Integer.toHexString(val & 0xff)中,相当于0xffffff8f & 0xff,得到的结果是0x8f。
(3) 返回char和short对应的16进制的字符串
“返回char对应的16进制的字符串”对应的源码如下:

private static String charToHexString(char val) { return Integer.toHexString(val);}

“返回short对应的16进制的字符串”对应源码如下:

private static String shortToHexString(short val) { return Integer.toHexString(val & 0xffff);}

比较上面的两个函数,为什么一个是 “val” ,而另一个是 “val & 0xffff”?
通过(2)的分析,我们类似的推出为什么 “返回short对应的16进制的字符串” 要执行“val & 0xffff”。
但是,为什么 “返回char对应的16进制的字符串” 要执行 “val” 即可。原因也很简单,java中char是无符号类型,占两个字节。将char转换为int类型,执行的是无符号转型,新增为都填充0。


DataOutputStream
DataOutputStream 是数据输出流。它继承于FilterOutputStream。
DataOutputStream 是用来装饰其它输出流,将DataOutputStream和DataInputStream输入流配合使用,“允许应用程序以与机器无关方式从底层输入流中读写基本 Java 数据类型”。
示例代码
关于DataOutStream中API的详细用法:

import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.ByteArrayInputStream;import java.io.File;import java.io.InputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.FileNotFoundException;import java.lang.SecurityException;/** * DataInputStream 和 DataOutputStream测试程序 * * @author skywang */public class DataInputStreamTest { private static final int LEN = 5; public static void main(String[] args) { // 测试DataOutputStream,将数据写入到输出流中。 testDataOutputStream() ; // 测试DataInputStream,从上面的输出流结果中读取数据。 testDataInputStream() ; } /** * DataOutputStream的API测试函数 */ private static void testDataOutputStream() { try { File file = new File("file.txt"); DataOutputStream out = new DataOutputStream( new FileOutputStream(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 (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * DataInputStream的API测试函数 */ private static void testDataInputStream() { try { File file = new File("file.txt"); DataInputStream in = new DataInputStream( new FileInputStream(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 (FileNotFoundException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 打印byte对应的16进制的字符串 private static String byteToHexString(byte val) { return Integer.toHexString(val & 0xff); } // 打印char对应的16进制的字符串 private static String charToHexString(char val) { return Integer.toHexString(val); } // 打印short对应的16进制的字符串 private static String shortToHexString(short val) { return Integer.toHexString(val & 0xffff); }}

运行结果:

byteToHexString(0x8F):0x8fcharToHexString(0x8FCF):0x8fcfreadBoolean():truereadByte():0x41readChar():0x4243readShort():0x4445readInt():0x12345678readLong():0xfedcba987654321readUTF():abcdefghijklmnopqrstuvwxyz严12

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章