我计划使用ByteArrayOutputStream将对象写入字节数组,然后将字节数组写入文件。我保持每个对象的位置。然后我从文件中读取,使用FileInputStream.getChannel()。position()重新定位位置,并调用ObjectInputStream.readObject()。
这是我的测试代码:
public static void main(String[] args) {
try {
HashBucketTest bucket1 = new HashBucketTest();
bucket1.putAddress("0", 30);
HashBucketTest bucket2 = new HashBucketTest(); // bucket2 key is the same as bucket3
bucket2.putAddress("22313", 40);
HashBucketTest bucket3 = new HashBucketTest();
bucket3.putAddress("22313", 50);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oops = new ObjectOutputStream(baos);
FileOutputStream fout = new FileOutputStream("objects.txt");
BufferedOutputStream bs = new BufferedOutputStream(fout);
int position1 = baos.size(); // the first object position
bs.write(baos.toByteArray()); // write head
baos.reset();
oops.writeObject(bucket1); // write the first object to byte array
int position2 = position1 + baos.size(); // the second object position
bs.write(baos.toByteArray()); // write first object to file
baos.reset();
oops.writeObject(bucket2); // write the second object to byte array
int position3 = position2 + baos.size(); // the third object position
bs.write(baos.toByteArray()); // write the second object to file
baos.reset();
oops.writeObject(bucket3); // write the third object to byte array
int position4 = position3 + baos.size(); // the fourth object position
bs.write(baos.toByteArray()); // write the third object to file
baos.reset();
bs.flush();
bs.close();
fout.flush();
fout.close();
// read according to the position x
HashBucketTest readCase1 = null;
HashBucketTest readCase2 = null;
HashBucketTest readCase3 = null;
FileInputStream fis = new FileInputStream("objects.txt");
ObjectInputStream ois = new ObjectInputStream(
fis);
// success case
readCase1 = (HashBucketTest) ois.readObject(); // read the first object, success
fis.getChannel().position(position2);
readCase2 = (HashBucketTest) ois.readObject(); // read the second object, success
fis.getChannel().position(position3);
readCase3 = (HashBucketTest) ois.readObject(); // read the third object, success
// failed case!!!!
//readCase1 = (HashBucketTest) ois.readObject(); // read the first object, success
//fis.getChannel().position(position3);
//readCase3 = (HashBucketTest) ois.readObject(); // read the third object, failed!!
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static class HashBucketTest implements Serializable {
private static final long serialVersionUID = 3610182543890121796L;
Map<String, Integer> values = null; // need to write to disk
public HashBucketTest() {
values = new TreeMap<String, Integer>();
}
public void putAddress(String key, int number) {
values.put(key, number);
}
}
我的问题是,当“bucket2”的键与“bucket3”(在这种情况下为“22313”)相同时。我看不懂bucket3 skippting bucket2
java.io.StreamCorruptedException: invalid handle value: 007E000C
at java.io.ObjectInputStream.readHandle(ObjectInputStream.java:1456)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1331)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2563)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2504)
at java.util.TreeMap.readObject(TreeMap.java:2450)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1896)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.alibaba.middleware.benchmark.Test.main(Test.java:146)
但如果关键不同,我可以成功完成。看来bucket3的关键是指桶2的?这很奇怪。无论如何,顺序阅读是可以的,但我不想要顺序阅读。
答案 0 :(得分:2)
我怀疑ObjectInputStream
并不是为这种用途而设计的。为了保持参照完整性,我怀疑有一个内部计数器用于“我写入流中的对象编号X”,随着对象的读取而增加 - 然后当有对该对象的引用时,它可以写为“参考编号X”。当您按照与写入顺序不同的顺序读取对象时,这会使事情变得非常糟糕。
我强烈建议你基本上不要尝试这样做。 (我还建议你尽可能避免常规的Java二进制序列化,但这是另一回事。)
答案 1 :(得分:2)
你不能这样做。对象输出流以流标头开始,并包含对已经序列化对象的反向引用。您不能将其视为单独序列化对象的随机访问序列。这是一条小溪。