import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Scanner;
public class FileDemo implements Serializable
{
static ArrayList<FileDemo> list=new ArrayList<FileDemo>();
public static void main(String[] args) throws Exception
{
File file=new File("log.txt");
if(!file.createNewFile() && file.length()!=0)
{
FileInputStream fis=new FileInputStream("log.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
while(true)
{
try{
list.add((FileDemo)ois.readObject());
}
catch(EOFException e) {
break;
}
catch(Exception e) {
e.printStackTrace();
break;
}
}
ois.close();
fis.close();
}
Scanner scn=new Scanner(System.in);
int x=0;
while(x!=3)
{
System.out.println("MENU");
System.out.println("Enter 1 to add new object to file");
System.out.println("Enter 2 to display list size");
System.out.println("Enter 3 to exit");
System.out.print("Enter your choice: ");
x=scn.nextInt();
if(x==1)
{
FileDemo filedemo=new FileDemo();
list.add(filedemo);
FileOutputStream fos=new FileOutputStream("log.txt",true);
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(filedemo);
oos.close();
fos.close();
System.out.println("Object Created");
}
else if(x==2)
{
System.out.println(list.size());
}
else if(x==3)
break;
else
System.out.println("Invaild choice");
}
}
}
Hi, In this program, everytime the user enters option 1 in the menu, a new object of the class is created, saved to the list and also saved to the file. When I try to read the objects from the file at the next execution of the program, it reads only the first object from the file and on the next readObject() call it raises an exception as follows:
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at FileDemo.main(FileDemo.java:25)
I would like to know how I can read all the objects stored in the file and add them to the list.
Thank You, Clement
An ObjectOutputStream is designed to write to a stream only once. It is not designed for appending. The simplest solution is to create a List
and write that list to a file. An alternative is to create your own protocol wrapping the object output stream though this might be more complicated.
In short, if you want to add an item you need to read where what was there, add the item to a list and replace/overwrite the file.
BTW a .txt
file should mean a text file, however, an Object stream is a binary file, so you should sue a different extension.
You could write it like this to give a clear separation between code to handle user input and the data structure which stores the user's data
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
public class FileDemo implements Serializable {
static class FileList implements Serializable {
List<FileData> list = new ArrayList<>();
}
static class FileData implements Serializable { }
public static void main(String[] args) throws IOException {
File file = new File("log.data");
FileList list = new FileList();
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
list = (FileList) ois.readObject();
}
}
Scanner scn = new Scanner(System.in);
while (true) {
System.out.print("MENU\n" +
"Enter 1 to add new object to file\n" +
"Enter 2 to display list size\n" +
"Enter 3 to exit\n" +
"Enter your choice: ");
int option = scn.nextInt();
switch (option) {
case 1:
list.list.add(new FileData());
File tmp = new File("log.data.tmp");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(tmp))) {
oos.writeObject(list);
}
Files.move(tmp.toPath(), file.toPath(), REPLACE_EXISTING);
System.out.println("Object Added");
break;
case 2:
System.out.println(list.list.size());
break;
case 3:
return;
default:
System.out.println("Invalid choice");
break;
}
}
}
}