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!
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
The solution is pretty simple. Here you have to handle
EOFException
. To do so you have to modify your code as follows -You're going to want to use FileInputStream and ObjectInputStream.
I know the topic is old but i thing i know the solution to this. The reason you get
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!
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;