简体   繁体   English

Java有选择地使用字节读取序列化的对象

[英]java reading serialized objects selectively using byte

I am trying to write a program which reads serialized objects selectively from a file given their byte offsets. 我正在尝试编写一个程序,该程序根据给定的字节偏移量有选择地从文件中读取序列化的对象。 I started by serializing three objects of same type in a file and then reading them using FileInputStream, ByteArrayInputStream and ObjectInputStream. 我首先将文件中的三个相同类型的对象序列化,然后使用FileInputStream,ByteArrayInputStream和ObjectInputStream读取它们。 But everytime I try to read a specific object it always returns me the first object. 但是每次我尝试读取一个特定的对象时,它总是返回我第一个对象。 Here is the small program : 这是小程序:

   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);
     }
    }

However everytime I run this program it displays only the first object (abc: 1.0). 但是,每次我运行该程序时,它仅显示第一个对象(abc:1.0)。 What could be the reason for this ? 这可能是什么原因? Is it not possible to read serialized objects like this ? 这样无法读取序列化的对象吗? Please ignore the efficiency issues as I am just trying to understand the concept and experiment. 请忽略效率问题,因为我只是想了解概念和实验。

ObjectOutputStream is a state machine it writes only increment data when you write mutiple objects, in order to write all data you can do ObjectOutputStream.reset() it will forget about previous writes and write fresh data with all information included. ObjectOutputStream是一个状态机,当您写入多个对象时,它仅写入增量数据,为了写入所有数据,您可以执行ObjectOutputStream.reset(),它将忘记先前的写入并写入包含所有信息的新数据。 Or you can create a new ObjectOutputStream for each object as Peter said. 或者,您可以按照Peter所说的为每个对象创建一个新的ObjectOutputStream。

From javadoc: 从javadoc:

The objects must be read back from the corresponding ObjectInputstream with the same types and in the same order as they were written. 必须从相应的ObjectInputstream中以与写入对象相同的类型和顺序读取对象。

如果不关闭流,请确保在writeObject之后进行刷新。

Also, you keep writing the entire byte[] to fos . 同样,您继续将整个byte[]写入fos So over your three calls you're doing: 因此,通过您的三个电话,您正在执行以下操作:

  1. Write object 1 写对象1
  2. Write object 1 & 2 写对象1和2
  3. Write object 1 & 2 & 3 写对象1&2&3

Instead, use write(byte[], int, int) . 而是使用write(byte[], int, int)

To read each object independently you need to write each object in its own ObjectOutputStream. 要独立读取每个对象,您需要将每个对象写入其自己的ObjectOutputStream中。 You can't start an ObjectStream anywhere except the start of the stream. 除了流的开始之外,您无法在任何地方启动ObjectStream。 However you can write multiple stream to a file and provided you know the start and end of the stream reconstitute the object. 但是,您可以将多个流写入文件,并且只要知道流的开始和结束即可重新构造对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM