我正在尝试读取我使用FileOutputStream类编写的二进制文件。我用来读它的类是RandomAccessFile类。
当我在十六进制编辑器中检查文件时,在我自己的实际数据前面似乎有大约9个额外字节。使用FileInputStream类读取时,这些数据似乎被忽略,但是对于RandomAccessFile,它不是。我做了一些研究,我相信这是一种块头。但是,我找不到具体的内容,并想问这个块头是什么。
以下是一些展示此问题的代码:
import java.io.*;
public class Main {
public static void main(String[] args) {
String path = "C:\\Users\\Fran\\Desktop\\test.bin"; //You should change this to a valid path on your computer
try {
FileOutputStream fstream = new FileOutputStream(path);
ObjectOutputStream ostream = new ObjectOutputStream(fstream);
ostream.writeInt(300);
ostream.close();
fstream.close();
FileInputStream fIn = new FileInputStream(path);
ObjectInputStream oIn = new ObjectInputStream(fIn);
System.out.println(oIn.readInt());
oIn.close();
fIn.close();
RandomAccessFile randomAccessFile = new RandomAccessFile(path,"r");
System.out.println(randomAccessFile.readInt());
randomAccessFile.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
正如您所看到的,RandomAccessFile不会返回与ObjectInputStream相同的内容,因为看起来ObjectInputStream忽略了所提到的块头。
谢谢。
答案 0 :(得分:0)
你的代码毫无意义。如果您使用ObjectOutputStream
进行书写,则必须使用ObjectInputStream
进行阅读。
这是Java对象序列化工作。如果不使用为此目的提供的工具,您不能指望阅读它。
您这里只使用writeInt()
和readInt()
,因此不清楚为什么要使用序列化。如果您没有使用writeObject()
或readObject()
和朋友,那么您应该使用DataInput/OutputStream
,它没有叠加协议。或者他可以使用DataOutputStream
,您可以谨慎使用RandomAccessFile
。
答案 1 :(得分:-1)
ObjectOutputStream
根据(缺乏想象力的名称)Object Serialization Stream Protocol写作。
文件的hexdump是:
ac ed 00 05 77 04 00 00 01 2c
分成块:
ac ed -> magic number java.io.ObjectStreamConstants.STREAM_MAGIC
00 05 -> version 5 java.io.ObjectStreamConstants.STREAM_VERSION
77 04 -> block of 4 bytes java.io.ObjectStreamConstants.TC_BLOCKDATA + length
00 00 01 2c -> the int32 300
使用RandomAccessFile
,您必须skipBytes(4)
(或者 - 可以说更好 - 检查文件标题实际上是ac ed 00 05
)并处理TC_BLOCKDATA