6 Replies Latest reply on Oct 25, 2006 2:19 PM by 807607

    writing and reading multiple serialized objects

    807607
      hello,

      if i serialize one object, write it in a binary file and read it again, it works fine.

      but i need to write multiple serialized-objects of the class into a
      binary file and want to read them later.

      how can i fix a delimiter for each obeject that is written to a file.
      and how do i retreive each object from the file.

      regards,
      Deepak.
        • 1. Re: writing and reading multiple serialized objects
          807607
          Unless I'm mistaken, you should be able to write multiple objects to a file, and then read them back:
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;
          import java.io.Serializable;
          
          public class SerialiseTest {
          
               /**
                * @param args
                */
               public static void main(String[] args) {
                    // TODO Auto-generated method stub
                    TestObject o1 = new TestObject(1);
                    TestObject o2 = new TestObject(2);
                    TestObject o3 = new TestObject(3);
               
                    try {
                         ObjectOutputStream oout = new ObjectOutputStream(
                                   new FileOutputStream("output.bin"));
                         
                         oout.writeObject(o1);
                         oout.writeObject(o2);
                         oout.writeObject(o3);
                         oout.flush();
                         oout.close();
                         
                         ObjectInputStream oin = new ObjectInputStream(
                                   new FileInputStream("output.bin"));
                         
                         Object ob1 = oin.readObject();
                         Object ob2 = oin.readObject();
                         Object ob3 = oin.readObject();
                         
                         System.out.println(o1);
                         System.out.println(o2);
                         System.out.println(o3);
                         
                    } catch (Exception exc){ 
                         exc.printStackTrace();
                    }
               }
          }
          
          class TestObject implements Serializable {
               private int foo;
               
               public TestObject(int i) {
                    foo = i;
               }
               
               public String toString() {
                    return "TestObject::"+foo;
               }
               
               public static final long serialVersionUID = 1l;
          }
          Serialising an object to a file is the same as writing it to a stream; you can continue reading objects from the stream until the stream is exhausted, and Java already handles the delimitation of objects

          J
          • 2. Re: writing and reading multiple serialized objects
            807607
            thanks that worked fine, i have a couple of more questions

            1. is there an easy way to find the number of serialized objects
            present in a stream, with the assumption that all the objects in that stream belong to the same class

            2. i had posted this question in another thread but cant find an answer

            i am serializing a class, the objects of that class are written into
            a binary file and later read from the binary file, however the objects
            need to be written in blocks.

            i.e. the binary file will look like

            [object1][object2][object3].....

            note: '[' ']' are for understanding and not present in the binary file

            each block needs to have a specific size,
            i.e. when i start reading the objects from the binary filr i will read
            in such a way that

            0-500 bytes correspond to 1st object
            501-1000 bytes correspond to 2nd object
            and so on...eventhough each object may occupy only 100 0r 200 0r whatever number of bytes in that block, the actual size will be known only at runtime but the size will be less than 500 bytes.

            for this reason i created a ByteBuffer
                            FileOutputStream fos = new FileOutputStream("c:\\test.dat");
                            ObjectOutputStream oos = new ObjectOutputStream(fos);
             
                      //writeSMSObjects is an object that has been serialized
                            Object obj = (Object)writeSMSObjects;
             
                            ByteArrayOutputStream bStream = new ByteArrayOutputStream();
                            ObjectOutputStream oStream = new ObjectOutputStream( bStream );
                            oStream.writeObject ( obj );
                            byte[] byteVal = bStream. toByteArray();
                            System.out.println("BYTE LENGTH: " + byteVal.length);
             
                      //Creating a ByteBuffer with a static size (objects that are serialized in each block will not exceed this size)
                            java.nio.ByteBuffer b1 = java.nio.ByteBuffer.allocate(500);
                            //writing the object into the ByteBuffer
                            b1.put(byteVal, 0, byteVal.length);
                            oos.write(b1.array());
                            
                            oos.flush();
                            fos.close();
                             oos.close();
            The writing part workd fine.

            when i try to read from the file
                        FileInputStream fis = new FileInputStream("c:\\test.dat");
                        ObjectInputStream ois = new ObjectInputStream(fis);
                        byte[] buffData = new byte[500];
                        ois.read(buffData, 0, 500);
                        System.out.println();
                        //Object o = ois.readObject();
                        WriteSMSObjects readSMSObjects = (WriteSMSObjects)ois.readObject();
            i get a java.io.OptionalDataException exception.
            i can see where the problem lies, each block is 500 bytes long however the object has occupied only 100 bytes (or so...) how can I extract deserialize the object correctly without knowing the number of bytes occupied by the objects in each block.


            regards,
            Deepak.
            • 3. Re: writing and reading multiple serialized objects
              807607
              hello,

              i did come up with a solution to find the number of objects in the serialized stream.
                          int objectsCount = 0;
                          boolean doneReadingInput = false;
                          while (!doneReadingInput){
                               System.out.println("***1");
                            Object result = null;
                            try { 
                                 System.out.println("***2");
                                 result = ois.readObject(); 
                            }
                            catch (EOFException eofe){
                                 System.out.println("***3");
                                 doneReadingInput = true;
                            }
                            catch (OptionalDataException ode) {
                                 System.out.println("***4");
                                 doneReadingInput = ode.eof; 
                                 
                            }
                         
                            if (result != null)
                            {
                                 System.out.println("***5");
                                 objectsCount++;
                                 WriteSMSObjects whatEver = (WriteSMSObjects)result;
                                 //Printing some value from the object
                               System.out.println(whatEver.getCommandID());
                            }
                          }
              
                          System.out.println("number of Objects are : " + objectsCount);
              but i still cant find a way to store objects inside a ByteBuffer, write that ByteBuffer in a file and extract the objects later...

              regards,
              Deepak.
              • 4. Re: writing and reading multiple serialized objects
                807607
                Why do you want to do this?

                ObjectOutputStream and ObjectInputStream handle the reading and writing of objects perfectly. Why are you trying to create a fixed allocation size per object? It seems ridiculously complicated for no visible gain?

                If you're trying to write some sort of database file, you should look at using DataOutputStream and DataInputStream, and then use these to output the variables from the object rather than the object itself, though this still seems silly if you're wanting to serialise entire objects.

                J
                • 5. Re: writing and reading multiple serialized objects
                  807607
                  i cant really come up with a proper explanation, the spec i had was designed for C and i was blindly trying to imitate the process where a Struct was converted to object and written into a buffer of fixed size and then written to the binary file.

                  i may not need that afterall.

                  ill come back if i have any more queries.

                  thanks,
                  Deepak.
                  • 6. Re: writing and reading multiple serialized objects
                    807607
                    ok,

                    the reason i am trying to fix size for each of my object is - i have multiple objects of same class serializzed to a binary file, objects from this file will be repetaedly accessed/changed and again re-written into the file, i want the reading/writing to be optimized for performance (the binary data written to file are SMS and there may be 40000+ objects in the file)

                    also the order in which the obejcts are written into must be preserved

                    I have to come up with a mechanism where i am able to select a particular object from a list of serialized objects, make some changes to it and re-write it back to the exat position, something like a replace function for serialized objects.