reading the serializable objects from file - java

List ll=new LinkedList();
Student temp;
int size = obj.readInt();
System.out.println(size);
for (int i = 0; i <size; ++i) {
ll.add((Student) obj.readObject());
}
obj.close();
System.out.println(ll);
}
it causes the run time exception as
"Exception in thread "main" java.io.EOFException
at java.io.DataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream.readInt(Unknown Source)
at p1.DeSerializeDemo1.main(DeSerializeDemo1.java:18)"
Please give me solution for this.

EOFException in ObjectInputStream.readInt means that there are less than 4 bytes left in the file after current position.

Just handle the Exception
try{
int size = obj.readInt();
}catch(EOFException ex){}

Why don't you create a class and save/load the entire object (that class needs to implement Serializable though (and all objects used it that class too)), then get the information you want using that object you can cast it afterwards:
public static Object load(String path) throws FileNotFoundException, Exception {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))) {
final Object result = ois.readObject();
ois.close();
return result;
}
}
public static void save(Object obj, String path) throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path))) {
oos.writeObject(obj);
oos.flush();
oos.close();
}
}

Exception cause is that you are not calling ObjectOutputStream.writeInt(int) before writing objects. As far as I understand you are trying to store number of objects, which is stored in the file. So, you should do it like this: obj.writeInt(2);
public class Test implements Serializable {
private static final long serialVersionUID = 243705916609512381L;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static void main(String[] args) {
Test s = new Test();
s.setName("Test");
Test s1 = new Test();
s1.setName("Test 2");
ObjectOutputStream oos = null;
FileOutputStream fileOutputStream = null;
FileInputStream fileInputStream = null;
ObjectInputStream ois = null;
try {
fileOutputStream = new FileOutputStream("C:\\test.txt");
oos = new ObjectOutputStream(fileOutputStream);
oos.writeInt(2);
oos.writeObject(s1);
oos.writeObject(s);
oos.flush();
oos.close();
fileOutputStream.close();
fileInputStream = new FileInputStream("C:\\test.txt");
ois = new ObjectInputStream(fileInputStream);
int readInt = ois.readInt();
System.out.println("Read int " + readInt);
Test readObject = (Test) ois.readObject();
System.out.println(readObject.getName());
Test readObject2 = (Test) ois.readObject();
System.out.println(readObject2.getName());
ois.close();
fileInputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// close everything
}
}

Related

how to write/read multiple object arrays using a text file [Java]

I want to write 3 object arrays to the same text file and load the data back to the arrays as well. However, I can only seem to get this to work with arr1 with the below code. How can I change this code to write the data of all 3 arrays to the same file and load the data back to their respective arrays?
import java.io.*;
public class CarCenter implements Serializable {
static CarCenter[] arr1 = new CarCenter[6];
static CarCenter[] arr2 = new CarCenter[6];
static CarCenter[] arr3 = new CarCenter[6];
public static void write() {
try {
FileOutputStream fos = new FileOutputStream("Data.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arr1);
oos.writeObject(arr2);
oos.writeObject(arr3);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void load() {
try {
FileInputStream fis = new FileInputStream("Data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
CarCenter[] saved = (CarCenter[]) ois.readObject();
arr1 = saved;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
In your code you are only loading the value of arr1:
public static void load() {
try {
FileInputStream fis = new FileInputStream("Data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
CarCenter[] saved = (CarCenter[]) ois.readObject();
arr1 = saved;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
All you have to do is to read the other objects as well like this:
public static void load() {
try {
FileInputStream fis = new FileInputStream("Data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
CarCenter[] saved = (CarCenter[]) ois.readObject();
arr1 = saved;
CarCenter[] saved2 = (CarCenter[]) ois.readObject();
arr2 = saved2;
CarCenter[] saved3 = (CarCenter[]) ois.readObject();
arr3 = saved3;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
Want to learn more?
I suggest reading the documentation itself.

Appendable Binary File

I'm working on appending objects to a binary file. My file is:
File f=new File("person.dat");
I'm getting an error (java.io.StreamCorruptedException: invalid stream header: 79737200) when I attempt to open the binary file. As far as I can tell the program writes the data just fine, but as soon as I try reading from it, I get the above error. Any help is appreciated!
My Code to write:
AppendObjectOutputStream out = null;
try {
out = new AppendObjectOutputStream(new FileOutputStream(f, true));
out.writeObject(new Student(name, age));
out.flush();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
out.close();
}
My class for making appendable:
public class AppendObjectOutputStream extends ObjectOutputStream {
public AppendObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {
reset();
}
}
My partial code for reading and adding objects to an ArrayList:
Course course = new Course();
Student st = null;
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new FileInputStream("person.dat"));
try
{
while (true)
{
st = (Student) in.readObject();
course.addAccount(st); //adds student object to an ArrayList in
//class Course
}
}
catch (EOFException ex) {
}
}
catch (Exception ex) {
ex.printStackTrace();
} finally {
in.close();
}
UPDATE:
Current code to read but its not printing anything to screen:
try(ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(Files.newInputStream(f))))
{
while (ois.available() > 0)
{
st = (Student) ois.readObject();
studentlist.addAccount(st);
System.out.println(st.getStudentNumber());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
This is how I write to file:
Path f = Paths.get("person.dat");
try (ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(Files.newOutputStream(f, StandardOpenOption.APPEND))))
{
oos.writeObject(new Student(name,age));
}
catch(Exception ex)
{
ex.printStackTrace();
}
Rather than trying to fix your utility classes, I suggest to use the standard classes of the NIO.2 File API.
Try something like (untested):
Path personDataFilePath = Paths.get("person.dat");
// or Java 11:
// Path personDataFilePath = Path.of("person.dat");
try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(Files.newOutputStream(personDataFilePath, StandardOpenOption.APPEND)))){
oos.writeObject(new Student(name,age));
} catch (IOException ex) {
// do some error handling here
}
and to read the file, something like (untested):
List<Student> students = new ArrayList<>();
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(Files.newInputStream(personDataFilePath)))){
while (ois.available() > 0){
students.add((Student) ois.readObject());
}
} catch (IOException ex) {
// do some error handling here
}
I have modified the code to work around making a file "appendable". I write a single arraylist object to the file (the arraylist holds a list of student objects). When I want to add a student, I read the object (arraylist) from the file, add my new student to the arraylist and write the arraylist back to the file. It is now working and my file does not have an append format.

ValidatingObjectInputStream throwing EOF exception

I am trying to build defense against Java deserialization vulnerability by using Apache API ValidatingObjectInputStream.
But it is failing with following exception and not sure what could be missing here:
Object has been serialized
IOException is caught
java.io.StreamCorruptedException: invalid stream header: 74000732
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:863)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:355)
at org.apache.commons.io.serialization.ValidatingObjectInputStream.<init>(ValidatingObjectInputStream.java:59)
at com.apple.ctbdp.controller.Test.deSerialize(Test.java:44)
at com.apple.ctbdp.controller.Test.main(Test.java:28)
Test.java
class Test {
public static void main(String[] args) {
String object = new String("2323232");
String filename = "file.ser";
serialize(object, filename);
deSerialize(filename);
}
private static void deSerialize(String filename) {
String object1 = null;
try {
// Reading the object from a file
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fis);
final ValidatingObjectInputStream objectInStream = new ValidatingObjectInputStream(fis);
objectInStream.accept(String.class);
// Method for deserialization of object
object1 = (String) objectInStream.readObject();
in.close();
fis.close();
System.out.println("Object has been deserialized ");
System.out.println("Test.deSerialize() " + object1);
}
catch (IOException ex) {
ex.printStackTrace();
System.out.println("IOException is caught");
}
catch (ClassNotFoundException ex) {
System.out.println("ClassNotFoundException is caught");
}
}
private static void serialize(String object, String filename) {
// Serialization
try {
// Saving of object in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
// Method for serialization of object
out.writeObject(object);
out.close();
file.close();
System.out.println("Object has been serialized");
}
catch (IOException ex) {
System.out.println("IOException is caught");
}
}
}
Appreciate your hint/suggestion in this regard.
I did not close the ValidatingObjectInputStream object, but instead was closing the ObjectInputStream object. With this change, it is now working.
Updated code:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import org.apache.commons.io.serialization.ValidatingObjectInputStream;
class Test {
public static void main(String[] args) {
String object = new String("2323232");
String filename = "file.ser";
serialize(object, filename);
deSerialize(filename);
}
private static void deSerialize(String filename) {
String object1 = null;
try {
// Reading the object from a file
FileInputStream fis = new FileInputStream(filename);
final ValidatingObjectInputStream objectInStream = new ValidatingObjectInputStream(fis);
objectInStream.accept(String.class);
// Method for deserialization of object
object1 = (String) objectInStream.readObject();
objectInStream.close();
fis.close();
System.out.println("Object has been deserialized ");
System.out.println("Test.deSerialize() " + object1);
}
catch (IOException ex) {
ex.printStackTrace();
System.out.println("IOException is caught");
}
catch (ClassNotFoundException ex) {
System.out.println("ClassNotFoundException is caught");
}
}
private static void serialize(String object, String filename) {
// Serialization
try {
// Saving of object in a file
FileOutputStream file = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(file);
// Method for serialization of object
out.writeObject(object);
out.close();
file.close();
System.out.println("Object has been serialized");
}
catch (IOException ex) {
System.out.println("IOException is caught");
}
}
}

Appending to ObjectOutputStream [duplicate]

This question already has answers here:
Appending to an ObjectOutputStream
(6 answers)
Closed 5 years ago.
I have a program utilizing the memento design pattern and want to save the state of each object into a file using serialization and return the object back. The problem is that I get a "java.io.StreamCorruptedException: invalid type code: AC" exception due to corrupt headers. I looked at Appending to an ObjectOutputStream and tried to implement the class but still can't get the program to work properly. Multiple objects should be saved in a file and the user passes a string into a function which should match part of the object's string representation.
public class Caretaker implements Serializable {
public void addMemento(Memento m) {
try {
// write object to file
FileOutputStream fos = new FileOutputStream("ConeOutput1.txt", true);
BufferedOutputStream outputBuffer = new BufferedOutputStream(fos);
AppendableObjectOutputStream objectStream = new AppendableObjectOutputStream(outputBuffer);
objectStream.writeObject(m);
objectStream.reset();
objectStream.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public Memento getMemento(String temp) {
try {
Memento result = null;
FileInputStream fis = new FileInputStream("ConeOutput1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
result = (Memento) ois.readObject();
while (result != null) {
Matcher m = Pattern.compile(temp).matcher(result.toString());
if (m.find()) {
return result;
}
else {
result = (Memento) ois.readObject();
}
ois.close();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
You should only use the appending ObjectOutputStream if the file already exists with data in it. If the file is new it needs the object stream header.

How do I save and multiple objects from a single file?

I want my app to store multiple objects locally for later use.
Now, my problem is that I know how to load an object from an ObjectInputStream by taking the entire file(federations.dat). Is there a way for me to load say object WHERE id = N from "federations.dat" ? Or do I have to create separate files for each object?
This is my load method:
public static Object load(Context ctx, String filename) throws FileNotFoundException
{
Object loadedObj = null;
InputStream instream = null;
instream = ctx.openFileInput(filename);
try {
ObjectInputStream ois = new ObjectInputStream(instream);
loadedObj = ois.readObject();
return loadedObj;
} catch (StreamCorruptedException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
Any suggestions come to mind ?
You can use it like this..
ArrayList<Object> arrayList = new ArrayList<Object>();
Object obj = null;
while ((obj = ois.readObject()) != null) {
arrayList.add(obj);
}
You can return an ArrayList on your method.
return arrayList;
Edit:
Full code would be like this..
public static ArrayList<Object> load(Context ctx, String filename)
{
InputStream fis = null;
ObjectInputStream ois = null;
ArrayList<Object> arrayList = new ArrayList<Object>();
Object loadedObj = null;
try {
fis = ctx.openFileInput(filename);
ois = new ObjectInputStream(fis);
while ((loadedObj = ois.readObject()) != null) {
arrayList.add(loadedObj);
}
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (null != ois) ois.close();
if (null != fis) fis.close();
}
return arrayList;
}
Hope it helps..
An extention to #Jan 's code, fixing the problem of keeping ois open if an exception is thrown, along with some minor issues.
public static ArrayList<Object> load(Context ctx, String filename) throws FileNotFoundException {
InputStream instream = ctx.openFileInput(filename);
ArrayList<Object> objects = new ArrayList<Object>();
try {
ObjectInputStream ois = new ObjectInputStream(instream);
try{
Object loadedObj = null;
while ((loadedObj = ois.readObject()) != null) {
objects.add(loadedObj);
}
return objects;
}finally{
ois.close();
}
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}

Categories

Resources