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!
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());
}
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With