java - Reading multiple objects from a file, as th

2020-05-24 10:16发布

I would like to ask the community what do you think about the following situation. The task is to write objects to a file. Which could be made by writing a list of objects to the file that I can read later so I have my objects again. Here, I would write practically ONLY ONE object to the file, namely the list (that may contain more objects).

But, the task seams to be to write separate objects to the file, which the method receives from a list. The objects can be whatever. (they must be serializable of course)

So I did:

public class TaskStream {
    public static void saveObjects(ArrayList<Object> al) {
        try {
            FileOutputStream fos = new FileOutputStream("outputFile", true);
            try {
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                for (Object o : al){
                    try {
                        oos.writeObject(o);
                        System.out.println("saved");
                    } catch (NotSerializableException e) {
                        System.out.println("An object was not serializable, it has not been saved.");
                        e.printStackTrace();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

This works just fine.

But now, I'd like to read them. My first concept about it would be a kind of method, that reads objects until the file has objects, and I can save each of them to a list again (that's the task). So like Pseudo code:

for(Object o : fileToRead){ list.add(o) }

How would it be possible? I started to play around with the readObject method of the ObjectInputStream, but it seems to lead to a lot of errors.

Do you have any idea? Or what would be the best practice by such a task?


Thanks!

I tried your idea. The exact implementation:

public static ArrayList<Object> readObjects(){
    ArrayList<Object> al = new ArrayList<Object>();
    boolean cont = true;
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("outputFile"));
            while(cont){
                  Object obj=null;
                try {
                    obj = ois.readObject();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                  if(obj != null)
                     al.add(obj);
                  else
                     cont = false;
               }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 return al;
}    

To test the program I will write two objects into the file. I read the objects from the file and add them to a list. I iterate through this list and print out the content.

If I run the program the following happens (I deleted the outputFile, so the program can recreate it and do everything from scratch).

Result:

The two objects from the list will be successfully printed. But I receive this:

java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2598)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1318)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)    

...

I don't change anything, and I run the program again. Result:

The two objects from the list will be successfully printed. But I receive this:

java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1377)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)    

From now on, any rerun brings the same result.

If I repeat the whole process from the very beginning again (starting by deleting the outputFile) everything happens exactly the same (as expected).

Do you have ideas how to fix it? Thank you very much for the help!

标签: java object
6条回答
聊天终结者
2楼-- · 2020-05-24 10:24
import java.io.*;
import java.util.*;
class ObjectReadWrite implements Serializable, Comparable <ObjectReadWrite>
{
    int no;
    String name;
    ObjectReadWrite(int i,String s)
    {
        this.no=i;
        this.name=s;
    }
    public String toString()
    {
        return "TP Data : "+this.no+":"+this.name;
    }
    public int compareTo(ObjectReadWrite a1)
    {
        return this.name.compareTo(a1.name);
    }
    public static void main(String args[]) throws Exception
    {
        TreeSet<ObjectReadWrite> aw = new TreeSet<ObjectReadWrite>();
        aw.add(new ObjectReadWrite(1,"ABC"));
        aw.add(new ObjectReadWrite(2,"DDF"));
        aw.add(new ObjectReadWrite(3,"DAF"));
        aw.add(new ObjectReadWrite(4,"DCF"));

        //Writing Objects From TreeSet
        ObjectOutputStream os=new ObjectOutputStream(
                    new FileOutputStream(
                    new File("Test.dat")));
        os.writeObject(aw);
        os.close();



        //Reading Objects into TreeSet
        TreeSet ar = new TreeSet();
        ObjectInputStream is=new ObjectInputStream(
                    new FileInputStream(
                    new File("Test.dat")));

        ar=(TreeSet)is.readObject();
        is.close();


        Iterator ir = ar.iterator();
        while(ir.hasNext())
        {
            System.out.println((ObjectReadWrite)ir.next());
        }

    }
}
查看更多
来,给爷笑一个
3楼-- · 2020-05-24 10:25

We can add all the object in a list and then serialize the list. Again we can deserialize the list and we can iterate over the list to get the objects , which we are looking for. It will require the use of below classes. FileOutputStream FileInputStream ObjectInputStream ObjectOutputStream

import java.io.Serializable;
import java.util.List;
import java.util.ArrayList;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

    public class MultiObjectSerialization {
        static String file = "helloFruits.txt";
        static ObjectOutputStream os;
        static ObjectInputStream is;

        public static void main(String[] args) throws IOException,
                ClassNotFoundException {
            Apples a = new Apples(1, "apple");
            Mango m = new Mango(2, "Mango");

            List<Object> fruits = new ArrayList<>();
            fruits.add(a);
            fruits.add(m);
            writeToFile(fruits);
            readFile();

        }

        public static void writeToFile(List<Object> fruits) throws IOException {
            os = new ObjectOutputStream(new FileOutputStream(file));
            os.writeObject(fruits);
            os.close();

        }

        public static void readFile() throws ClassNotFoundException, IOException {
            is = new ObjectInputStream(new FileInputStream(file));
            List<Object> input = (List<Object>) is.readObject();
            List<Object> checkList = new ArrayList<>();
            // this will contain the list of the objects
            for (Object l : input) {
                checkList.add(l.getClass().getSimpleName());
                if (l instanceof Apples) {
                    Apples app = (Apples) l;
                    System.out.println(app.id);
                    System.out.println(app.name);
                }
                if (l instanceof Mango) {
                    Mango app = (Mango) l;
                    System.out.println(app.id);
                    System.out.println(app.name);
                }
            }
            System.out.println(checkList);

            is.close();
        }
    }

    class Apples implements Serializable {
        private static final long serialVersionUID = 1L;
        int id;
        String name;

        public Apples(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }

    class Mango implements Serializable {
        private static final long serialVersionUID = 1L;
        int id;
        String name;

        public Mango(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }


  The Output is ::
    1
    apple
    2
    Mango
    [Apples, Mango]
查看更多
再贱就再见
4楼-- · 2020-05-24 10:28

The solution is pretty simple. Here you have to handle EOFException. To do so you have to modify your code as follows -

try {
    obj = ois.readObject();
} catch (EOFException e) {
    break;
}
查看更多
够拽才男人
5楼-- · 2020-05-24 10:29

You're going to want to use FileInputStream and ObjectInputStream.

FileInputStream fis = new FileInputStream("outputFile");
ArrayList<Object> objectsList = new ArrayList<>();
boolean cont = true;
while (cont) {
  try (ObjectInputStream input = new ObjectInputStream(fis)) {
    Object obj = input.readObject();
    if (obj != null) {
      objectsList.add(obj);
    } else {
      cont = false;
    }
  } catch (Exception e) {
    // System.out.println(e.printStackTrace());
  }
}
查看更多
叛逆
6楼-- · 2020-05-24 10:29

I know the topic is old but i thing i know the solution to this. The reason you get

`'invalid type code: AC'`

is because after you write one object and you try to read it , the ObjectInputStream is trying to read the info your ObjectOutputStream wrote. That's how serialization works in general. The problem on your code is that a new ObjectInputStream is getting created and tries to read back from an old ObjectOutputStream and it finds out that they don't have the same serial code so you get this error.

I found a solution at another topic posted some time ago , check here :stackoverflow solution

What he is doing is that he is overridng the streamWriter which "tricks" the ObjectInputStream to believing that he can read the ObjectOutputStream.

Hope thats helpfull. Peace out!

查看更多
别忘想泡老子
7楼-- · 2020-05-24 10:36

We've to used FileInputStream class method "available" method to check that given stream has data or bytes to read or not if data is not present then this method will return 0;

public static ArrayList<Object> getObjects(){

    ArrayList<Object> objects = new ArrayList<Object>(); 
    FileInputStream fis = new FileInputStream("outputFile");
    ObjectInputStream ois = new ObjectInputStream(fis);

    Object obj =null;

    boolean isExist = true;

    while(isExist){
        if(fis.available() != 0){
         obj = (A) ois.readObject();    
         objects.add(obj);
        }
        else{
        isExist =false;
        }
    }
    return objects;     
}
查看更多
登录 后发表回答