【0】README
0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——读写二进制数据(DataOutput + DataInput)的相关知识;
0.2) for complete my diy code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter1/BinaryIO.java
【1】DataOutput
1.0)DataOutput 接口定义 了 下面用于以二进制格式写数组, 字符, boolean 和 字符串的方法:
writeChars, writeByte, writeInt, writeShort, writeLong, writeFloat, writeDouble, writeChar, writeBoolean, writeUTF;
1.1)例如, writeInt 总是将一个整数写出为 4字节的二进制数量值;
1.2)不管它有多少位, writeDouble 总是将一个double值写出为 8 字节的二进制数量值;
1.3)这样产生的结果并非人可阅读的, 但是对于给定类型的每个值, 所需的空间总是相同的, 而且将其读回也比解析文本要更快;(干货——解析二进制数据比解析文本数据要更快)
Attention)
- A1)在 java中,所有的值都按照 高位在前的模式写出, 不管使用何种处理器, 这使得java 数据文件独立于平台;
- A2) 如 1234(10)=4D2(16): 高位在前顺序为 00 00 04 D2 ; 而 低位在前顺序为 D2 04 00 00;
【2】 writeUTF方法:
2.1)writeUTF方法 使用修订版的8位 Unicode转换格式写出字符串;这种方式与直接使用标准的UTF-8 编码方式不同, 其中, Unicode码元序列首先用 UTF-16 表示, 其结果之后使用 UTF-8 规则进行编码;
2.2)修订后的 编码方式对于编码大于 0xFFFF 的字符的处理有所不同, 这是为了向后兼容在Unicode 还没有超过16 位时构建的虚拟机;
Attention) (干货——如何使用 writeChars 和 writeUTF 方法)
- A1)因为没有其他方法会使用 UTF-8 的这种修订, 所以你应该只在写出用于 java 虚拟机的字符串时才使用 writeUTF方法;例如,当需要编写一个生产字节码序列的程序时;
- A2)而对于其他场合, 都应该使用 writeChars 方法;
【3】DataInput方法: 为了读回数据, 可以使用在 DataInput 接口中定义的下列方法:
- readInt, readShort, readLong, readFloat, readDouble, readChar, readBoolean, readUTF;
3.1)读入二进制数据: DataInputStream 类实现了DataInput接口, 为了从文件中读取二进制数据, 可以将 DataInputStream与某个字节源进行组合, 如 FileInputStream:
DataInputStream dis = new DataInputStream(new FileInputStream(“employee.dat”));
3.2)写出二进制数据: DataOutputStream dos = new DataOutputStream(new FileOutputStream(“employee.dat”));
【4】随机访问文件(RandomAccessFile 同时实现了 DataInput 和 DataOutput 接口)
- Attention) for detailed RandomAccessFile, please visit http://blog.csdn.net/PacosonSWJTU/article/details/50513407
4.0)RandomAccessFile 类 : 可以 在文件中任何位置查找或写入数据;(干货——这是引入 RandomAccessFile 类的原因)
4.1) RandomAccessFile类可以在文件中的任何位置查找或读写数据;
4.2)磁盘文件都是可以随机访问的, 但是从网络而来的数据流却不是;
4.3)打开一个随机访问文件,只用于读入或同时用于读写;
RandomAccessFile in= new RandomAccessFile("employee.dat", "r");
RandomAccessFile inOut = new RandomAccessFile("employee.dat", "rw");
4.4)seek 方法:随机访问文件有一个表示下一个将被读入或写出的字节所处的位置的文件指针, seek 方法可以将这个文件指针设置到 文件中任意字节 的位置;
- 4.4.1)假设想读入第三条数据:
long n = 3;
in.seek((n-1) * RECORD_SIZE); - 4.4.2)如果你希望修改数据,请切记将文件指针重置到开始处:
in.seek((n-1) * RECORD_SIZE);
e.writeData(out); - 4.4.3)length 方法:确定文件大小,使用 length 方法;
4.5) 整数和浮点值在二进制格式中都有固定的尺寸, 但处理 字符串就有些麻烦了, 我们提供了 两个助手方法来读写具有固定尺寸的字符串:
- writeFixedString 方法: 写出从字符串开头开始的指定数量的码元;
- readFixedString 方法: 从输入流中读入字符, 直至读入size 个码元, 或者直至到具有0值的字符值, 然后跳过输入字段中剩余的 0值;为了提高效率,使用 StringBuilder 类来读入字符串;