我正在尝试编写一个程序,在给定字节偏移的情况下,从文件中有选择地读取序列化对象。我首先在文件中序列化三个相同类型的对象,然后使用FileInputStream,ByteArrayInputStream和ObjectInputStream读取它们。但每当我尝试读取特定对象时,它总会返回第一个对象。 这是一个小程序:
public class TestObject implements Serializable {
String term;
double value;
public TestObject(String term, double value) {
this.term =term;
this.value = value;
}
public String toString() {
String str = term + " : " + value;
return str;
}
}
public class ObjectReader {
public static void main(String[] args) throws IOException,ClassNotFoundException {
TestObject t1 = new TestObject("abc", 1.0);
TestObject t2 = new TestObject("xyz", 1.0);
TestObject t3 = new TestObject("123", 1.0);
//Writing 3 objects to file and displaying offsets
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(baos);
FileOutputStream fos = new FileOutputStream("data.dat");
objOut.writeObject(t1);
byte[] arr = baos.toByteArray();
System.out.println(arr.length); //displays 81
fos.write(arr);
objOut.writeObject(t2);
arr= baos.toByteArray();
System.out.println(arr.length); //displays 101
fos.write(arr);
objOut.writeObject(t3);
arr= baos.toByteArray();
System.out.println(arr.length); //displays 121
fos.write(arr);
fos.close();
objOut.close();
//Reading a specific object back using offset
FileInputStream fis = new FileInputStream("data.dat");
byte[] inArr = new byte[101];
fis.skip(81); //skip to second object
fis.read(inArr);
System.out.println(fis.available()); //displays 121 which is correct
ByteArrayInputStream bain = new ByteArrayInputStream(inArr);
ObjectInputStream objIn = new ObjectInputStream(bain);
TestObject t4 =(TestObject)objIn.readObject();
System.out.println(t4);
}
}
但是每次运行此程序时,它只显示第一个对象(abc:1.0)。这可能是什么原因?是不是可以读取这样的序列化对象?请忽略效率问题,因为我只是想了解这个概念和实验。
答案 0 :(得分:0)
如果你没有关闭流,请确保在writeObject之后执行刷新。
答案 1 :(得分:0)
此外,您还要将整个byte[]
写入fos
。所以在你正在做的三个电话中:
相反,请使用write(byte[], int, int)
。
答案 2 :(得分:0)
要独立读取每个对象,您需要在自己的ObjectOutputStream中编写每个对象。除了流的开头之外,您无法在任何地方启动ObjectStream。但是,您可以将多个流写入文件,并且如果知道流的开头和结尾重构该对象。
答案 3 :(得分:0)
ObjectOutputStream是一个状态机,当你编写多个对象时它只写增量数据,为了写入你可以做的所有数据ObjectOutputStream.reset()它会忘记以前的写入并写入包含所有信息的新数据。或者你可以像Peter所说的那样为每个对象创建一个新的ObjectOutputStream。
来自javadoc:
对象必须从相应的ObjectInputstream中读回,其类型和顺序与写入时相同。