JAVA Bin IO with Objects - java

I'm having an issue reading and loading objects to and from a BIN file i keep getting the errors "java.io.WriteAbortedException" and "java.io.NotSerializableException". This is even when my Student object implements Serializable...
LOADER:
try{
FileInputStream fis = new FileInputStream("students.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
while(true){
Student[] stu = null;
int i = 0;
try {
stu = (Student[]) ois.readObject();
studentBag.add(stu[i]);
} catch (EOFException e) {
break;
}
System.out.println(student);
i++;
}
SAVER:
Student[] studentArray = new Student[2];
studentArray[0] = student;
try {
FileOutputStream fos = new FileOutputStream("students.dat", true);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(studentArray);
oos.flush();
oos.close();
} catch (FileNotFoundException e) {
System.out.println("File not found");
} catch (IOException e) {
System.out.println("Nope");
}
Yes I did close the try catches just didnt see a point in putting them here.
Also im getting the errors at this line in the Loder stu = (Student[]) ois.readObject();
and this in the saver studentArray[0] = student;

Related

readObject is not reading all element of Linkedlist from the file

I am able to write data (serialize Object) into the file correctly but while reading the data I am only getting the first one. What is the problem in my code? I think I am deserializing object in correct way, because I checked it in some others code, they are also doing in the same way.
My files are like this :
Main.java
package com.company;
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
int i =0;
int choice = 0;
ListIterator iterator;
Scanner sc = new Scanner(System.in);
LinkedList<Employee> employeeList = new LinkedList<Employee>();
LinkedList<Employee> employeeArrayList ;
File file = new File("./src/com/company/employeeInfo.txt");
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
FileInputStream fileInputStream = null;
Employee employee = new Employee();
while(true)
{
System.out.println("Main Menu");
System.out.println("1.Add an Employee");
System.out.println("2.Display All");
System.out.println("3.Exit");
choice = Integer.parseInt(sc.nextLine());
switch (choice)
{
case 1:
System.out.print("Enter Employee ID : ");
employee.id = Integer.parseInt(sc.nextLine());
System.out.println(" Enter Employee Name : ");
employee.name = sc.nextLine();
System.out.println("Enter Employee Age : ");
employee.age = Integer.parseInt(sc.nextLine());
System.out.println("Enter Employee Salary : ");
employee.salary = Double.parseDouble(sc.nextLine());
System.out.println(employeeList.add(employee));
try{
fileOutputStream = new FileOutputStream(file,true);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(employeeList);
objectOutputStream.close();
}
catch (IOException | NullPointerException exception)
{
System.out.println(exception.getMessage());
}
break;
case 2:
try {
System.out.println("----Report----");
// sc = new Scanner(file);
fileInputStream = new FileInputStream(file);
objectInputStream = new ObjectInputStream(fileInputStream);
employeeArrayList = (LinkedList<Employee>) objectInputStream.readObject();
iterator = employeeArrayList.listIterator();
System.out.println(employeeArrayList);
while (iterator.hasNext())
{
employee = (Employee) iterator.next();
System.out.println(employee.toString() );
}
}
catch (FileNotFoundException | NullPointerException e )
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
System.out.println(e.getMessage());
}
break;
case 3:
try
{
objectInputStream.close();
fileInputStream.close();
}
catch (IOException e)
{
System.out.println(e);
}
System.exit(0);
break;
}
}
}
}
Employee.java
package com.company;
import java.io.Serializable;
public class Employee implements Serializable {
int id;
String name;
int age ;
double salary;
public String toString() {
return id+" "+name +" "+age+" "+salary ;
}
}
The problem is that you are opening the file in "append" mode. This is controlled by the boolean true parameter you pass to FileOutputStream constructor:
fileOutputStream = new FileOutputStream(file,true);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
In the "append" mode, what you write to the file is added to the end of the file ("appended"). The existing contents of the file are not replaced, which is what you seem to want.
Solution: stop using the append mode. This will replace the old contents of the file with the new content you are writing.
fileOutputStream = new FileOutputStream(file);
objectOutputStream = new ObjectOutputStream(fileOutputStream);

Modifying objects in binary file

Considering I have an object from a custom class and I write it to a .dat file using FileOutputStream and ObjectOutputStream . How will I modify a object present in the file? I can only read or write objects into a file..
I know that we can create a temporary file and then renaming the file accordingly, but isnt there any other way?
I do get outputs as expected , but isnt there any other method?
Yes you can do it by using FileOutputStream & ObjectOutputStream class
class MyBean {
public String firstvalue;
public String secondvalue;
public MyBean (String firstvalue,String secondvalue){
this.firstvalue=firstvalue;
this.secondvalue=secondvalue;
}
}
public class FileSerialization {
public static void main(String[] args) {
try {
MyBean mb = new MyBean("first value", "second value");
// write object to file
FileOutputStream fos = new FileOutputStream("mybean.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(mb);
oos.close();
// read object from file
FileInputStream fis = new FileInputStream("mybean.dat");
ObjectInputStream ois = new ObjectInputStream(fis);
MyBean result = (MyBean) ois.readObject();
ois.close();
System.out.println("One:" + result.firstvalue + ", Two:" + result.secondvalue);
result.firstvalue="Changed;";
// write object to file
fos = new FileOutputStream("mybean.dat");
oos = new ObjectOutputStream(fos);
oos.writeObject(result);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

Reading after appending objects to serialized file in Java [duplicate]

This question already has answers here:
How to write data with FileOutputStream without losing old data?
(2 answers)
Closed 5 years ago.
I am writing to a stream file in Java. I have read if I want to append I need to override WriteStreamHeader. But even after doing so, I am not able to get free from StreamCorruptedException.
class AppendingObjectOutputStream extends ObjectOutputStream {
public AppendingObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
protected void writeStreamHeader() throws IOException {
reset();
}
}
class Student implements Operations,Serializable
{
private static final long serialVersionUID = 1L;
private int studid;
private String sname;
private int sage;
private long contact;
public Student()
{
studid = 0;
sname = null;
sage = 0;
contact = 0;
}
public void add(Scanner sc)
{
System.out.print("Enter student id: ");
studid = Integer.parseInt(sc.nextLine());
System.out.print("Enter student name: ");
sname = sc.nextLine();
System.out.print("Enter student age: ");
sage = Integer.parseInt(sc.nextLine());
System.out.print("Enter student's contact number: ");
contact=Long.parseLong(sc.nextLine());
}
public void show()
{
System.out.println("Student's details:");
System.out.println("Id no: "+studid);
System.out.println("Name :" + sname);
System.out.println("Age :" + sage);
System.out.println("Contact No. :" + contact);
}
}
class Admin
{
public void addstu(Scanner sc)
{
try
{
Student s = new Student();
s.add(sc);
boolean b = true;
FileInputStream fis = null;
try{
fis = new FileInputStream("student.ser");
fis.close();
}
catch (FileNotFoundException e)
{
b = false;
}
FileOutputStream fos = new FileOutputStream("student.ser");
ObjectOutputStream oos =null;
if(b == true)
{
System.out.println("Appending objects");
oos = new AppendingObjectOutputStream(fos);
}
else
{
System.out.println("Writing objects");
oos = new ObjectOutputStream(fos);
}
oos.writeObject(s);
oos.close();
fos.close();
System.out.println("Student successfully inserted");
fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Student result = (Student) ois.readObject();
result.show();
ois.close();
fis.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public void displayallstu()
{
try
{
FileInputStream fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.println("Student's List");
try{
while(true)
{
Student result = (Student) ois.readObject();
result.show();
}
}
catch (EOFException e) {
System.out.println("!!End of file!!");
}
finally{
ois.close();
fis.close();}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
It is called from main and executes properly when addstu() is called for the first time, but when called for next time, displays Successfully Inserted message, but throws exception while reading.
java.io.StreamCorruptedException: invalid stream header: 79737200
What you first generate is:
stream header
student
Then you are overwriting this with:
reset
student
which cannot be read since you’re missing the stream header. You want the following in the file:
stream header
student
reset
student
To get this, you will need to open the output stream in append mode after the file has been created the first time. Since you already have a Boolean indicating if this is necessary, just pass that to the constructor:
FileOutputStream fos = new FileOutputStream("student.ser", b);

java.io.EOFException when reading an object through ObjectInputStream

Wrote a simple piece of code top serialize standard employee object and deserialize it in the the same machine from different class. Both programs compiled and executed Obj output stream to create serialized object.
Problem is with deserializing it. Program when run gives EOF exception.
Here is the code I am using:
Serialize-
import java.io.*;
public class OOStreamDemo{
public static void main(String []a){
Employee e = new Employee("Abhishek Yadav", 'i', 10014);
FileOutputStream fout = null;
ObjectOutputStream oout = null;
try{
fout = new FileOutputStream("emp.ser");
oout = new ObjectOutputStream(fout);
} catch(Exception ex1){
System.out.println(oout);
ex1.printStackTrace();
}
finally{
try{
oout.flush();
oout.close();
fout.close();
} catch(IOException ex2){
ex2.printStackTrace();
}
}
}
}
Deserialize -
import java.io.*;
public class OIStreamDemo{
public static void main(String []a){
System.out.println("Inside main");
FileInputStream fin = null;
ObjectInputStream oin = null;
Employee emp;
try{
System.out.println("Inside try");
fin = new FileInputStream("emp.ser");
oin = new ObjectInputStream(fin);
System.out.println("Streams Initialized");
while((emp = (Employee)oin.readObject()) != null)
{
System.out.println(emp.toString());
}
System.out.println("Object read");
//System.out.println("Read object is " + emp);
//System.out.println("Obj props are "+ emp.name);
} catch(Exception e){
e.printStackTrace();
}
}
}
This is the printStackTrace:
Inside main
Inside try Streams
Initialized
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)
at OIStreamDemo.main(OIStreamDemo.java:16)
Thank You.
You did not write the Employee object to the ObjectOutputStrem therefore add
oout.writeObject(e);

How to save values as an ArrayList of double in file

I want to save values as an ArrayList of double in a file. Whenever there is new value, it should be added in an ArrayList without erasing the previous ones. I'm try to use the function,DataStream. Is it possible? If its possible, please let me know how to implement that.
Please refer below code .
private static String LFILE = "serial";
public static void updateFile(Double num) {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try{
List<Double> list = getDoubles();
list.add(num);
fos = new FileOutputStream(LFILE);
oos = new ObjectOutputStream(fos);
oos.writeObject(list);
}catch(Exception e){
e.printStackTrace();
try {
oos.close();
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public static List<Double> getDoubles() {
FileInputStream fis = null;
ObjectInputStream ois = null;
List<Double> newList = new ArrayList<Double>();
try {
fis = new FileInputStream(LFILE);
ois = new ObjectInputStream(fis);
newList = (ArrayList<Double>) ois.readObject();
} catch (Exception ex) {
try {
fis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return newList;
}
The class you want to use are ObjectOutputStream and ObjectInputStream
e.g.
http://www.javadb.com/writing-objects-to-file-with-objectoutputstream
http://www.javadb.com/reading-objects-from-file-using-objectinputstream
XStream is a library for Java which supports save/send objects in a xml-format. It is simple to use. XML is human readable making it easy to check its corrent or modify.

Categories