So guys i need some help. I have a class Book and i want to save my books object to a Stream and then read this Stream file so i can search my objects from there. I have written my code but it gives me some errors and i can figure out how to print my books values .
So this is my Book class
public class Book {
private Date arr;
private Date depp;
private Type room;
private boolean breakfast = false;
private Person data;
private ObjectOutputStream out;
public Book(String name, String surename, String phone,Date arr, Date depp, Type room, boolean breakfast) {
data = new Person(name,surename,phone);
this.arr = arr;
this.depp = depp;
this.room = room;
this.breakfast = breakfast;
}
public void writeObjToFile(){//here i save my object to stream it gives me error, i call this method after i create my book object to main
try{
out = new ObjectOutputStream(new FileOutputStream("books.txt"));
out.writeObject(this);
}
catch(FileNotFoundException e){
System.err.println("File not Found");
e.printStackTrace();
}catch(IOException e){
System.err.println("IOException");
e.printStackTrace();}
}
}
and this is my Search class :
public class Search {
private FileInputStream fis=null;
private String filename;
public Search(String filename){
this.filename = filename;
File file = new File(filename);
try {
fis = new FileInputStream(file);
System.out.println("Total file size to read (in bytes) : "
+ fis.available());
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Book should implement Serializable
Check the API
https://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html#writeObject%28java.lang.Object%29
Also, remove the out member from Book class because it's not Serializable either.
Related
I have a file which is storing objects and I have a *getAll() method which needs to return the List<Secretary>. But, I only see single object being printed in console.
I searched for the problem and tried 3 ways but it did not work.
The insert method for inserting object in file is:
#Override
public Secretary insert(Secretary t) {
try {
System.out.println("insert called");
FileOutputStream file = new FileOutputStream
(filename,true);
ObjectOutputStream out = new ObjectOutputStream
(file);
Method for serialization of object
out.writeObject(t);
out.close();
file.close();
return t;
}
catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
I have declared append mode as true as, my file was being replaced by new object when saving.
So,i need to fetch all object from file and need to assign to a list.I tried:
public class SecretaryDaoImpl implements SecretaryDAO{
private String filename = "secretary.txt";
private Secretary sec=null;
#Override
public List<Secretary> getAll() {
//Method 1
try {
Reading the object from a file
FileInputStream file = new FileInputStream
(filename);
ObjectInputStream in = new ObjectInputStream
(file);
List<Secretary> secList=new ArrayList<>();
Method for deserialization of object
secList.add((Secretary)in.readObject());
in.close();
file.close();
System.out.println("Object has been deserialized\n"
+ "Data after Deserialization.");
System.out.println("secList is" +secList);
return secList;
}
catch (IOException ex) {
System.out.println("Secreatary file not found");
return null;
}
catch (ClassNotFoundException ex) {
System.out.println("ClassNotFoundException" +
" is caught");
}
return null;
//Method 2
List<Secretary> secList=new ArrayList<>();
ObjectInputStream objectinputstream = null;
try {
FileInputStream streamIn = new FileInputStream(filename);
objectinputstream = new ObjectInputStream(streamIn);
List<Secretary> readCase = (List<Secretary>) objectinputstream.readObject();
for(Secretary s:readCase){
secList.add(s);
}
System.out.println("seclist is" + secList);
return secList;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(objectinputstream != null){
try {
objectinputstream.close();
} catch (IOException ex) {
Logger.getLogger(SecretaryDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//Method 3
try{
File file = new File(filename);
List<Secretary> list = new ArrayList<>();
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
list.add((Secretary) ois.readObject());
}
}
System.out.println("getall is"+list);
}
catch(Exception e){
}
return null;
}
}
I have commented out my code but here while posting in stackoverflow I have uncommented all the codes.
My Secretary.java is :
package com.npsc.entity;
import java.io.Serializable;
/**
*
* #author Ashwin
*/
public class Secretary implements Serializable {
private static final long serialVersionUID = 6529685098267757690L;
private int id;
private String userName;
private String password;
private Branch branch;
public String getUserName() {
return userName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Secretary(String userName, String password) {
this.userName = userName;
this.password = password;
}
public Branch getBranch() {
return branch;
}
public void setBranch(Branch branch) {
this.branch = branch;
}
#Override
public String toString() {
return "Secretary{" + "id=" + id + ", userName=" + userName + ", password=" + password + ", branch=" + branch + '}';
}
}
While performing insert operation,my txt file saving objects is:
But,I am unable to read all the object and add in list.Where I am facing the problem?
You will need to store in the file, the number of Secretary objects to read back. You can then determine how many entities to read, and thus repopulate your list.
Something like:
List<Secretary> list;
private void persistList(ObjectOutputStream out) {
out.writeInt(list.size());
for (Secretary sec : list) {
out.writeObject(sec);
}
}
And then to read:
private List<Secretary> readFromStream(ObjectInputStream in) {
int numObjects = in.readInt();
List<Secretary> result = new ArrayList<>(numObjects);
for (int i = 0; i < numObjects; i++) {
result.add((Secretary)in.readObject());
}
return result;
}
This is just a sketch of the technique (and ignores error handling, stream opening/closing etc.); the main thing is to integrate the idea of recording the size of the list, then reading that many Secretaries into your existing code.
Write a List<Secretary> to file and read same back, then you will have all.
write (Secretary s) {
read List<Secretary> currentList ;
currentList.add(s)
write List<Secretary>
}
I use ObjectInput/Output to initialize the hashmap named temp and it put all entry of the hashmap called map that is initialized to new and then use OutputStream to save it in file formatting is .ser
this work perfectly...
import java.io.*;
import java.util.HashMap;
public class PlayerInfo implements Serializable {
ObjectOutputStream out;
ObjectInputStream in;
File userData =new File("path.ser");
HashMap map ;
HashMap temp;
private Integer ID;
String name ;
boolean isItNull =false;
public static void main(String[] args) {
new PlayerInfo();
}
PlayerInfo(){
try {
initializeHashMap();
}catch (Exception e){
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
private void initializeHashMap(){
try {
//initialize ObjectInputStream in same method when I use it and close it then
in =new ObjectInputStream(new FileInputStream(userData));
if (isItNull){
temp =new HashMap<Integer,PlayerInfo>();
}else {
map =new HashMap<Integer,PlayerInfo>();
temp = (HashMap<Integer, PlayerInfo>) in.readObject();
in.close();
}
}catch (Exception e){
isItNull =true;
initializeHashMap();
}
}
private void getInfo(){
System.out.println("Ok we are in get info so write your ID:-");
int id = 10;
}
#SuppressWarnings("unchecked")
private void createInfo()throws IOException{
//same here initialize ObjectOutputStreamin same method when I use it and close it then
out =new ObjectOutputStream(new FileOutputStream(userData));
System.out.println("Ok we are in create info so write your ID:-");
ID =10;
String scnS ="Mohammed";
System.out.println("Write your name");
map.put(ID,new PlayerInfo(scnS));
temp.putAll(map);
System.out.println("Saving....");
out.writeObject(temp);
out.close();
}
public PlayerInfo(String name){
this.name =name;
}
}
but this throw EFOException
import java.io.*;
import java.util.HashMap;
public class PlayerInfo implements Serializable {
ObjectOutputStream out;
ObjectInputStream in;
File userData =new File("path.ser");
HashMap map ;
HashMap temp;
private Integer ID;
String name ;
boolean isItNull =false;
public static void main(String[] args) {
new PlayerInfo();
}
PlayerInfo(){
try {
openTheOutPutObjectStreamer();
openTheInPutObjectStreamer();
initializeHashMap();
}catch (Exception e){
e.printStackTrace();
}
}
//here I initialize it in separated method
private void openTheOutPutObjectStreamer()throws IOException{
out =new ObjectOutputStream(new FileOutputStream(userData));
}
//same here I initialize it in separated method
private void openTheInPutObjectStreamer()throws IOException{
in =new ObjectInputStream(new FileInputStream(userData));
}
#SuppressWarnings("unchecked")
private void initializeHashMap(){
try {
if (isItNull){
temp =new HashMap<Integer,PlayerInfo>();
}else {
map =new HashMap<Integer,PlayerInfo>();
temp = (HashMap<Integer, PlayerInfo>) in.readObject();
in.close();
}
}catch (Exception e){
isItNull =true;
initializeHashMap();
}
}
#SuppressWarnings("unchecked")
private void createInfo()throws IOException{
System.out.println("Ok we are in create info so write your ID:-");
ID =10;
String scnS ="Mohammed";
System.out.println("Write your name");
map.put(ID,new PlayerInfo(scnS));
temp.putAll(map);
System.out.println("Saving....");
out.writeObject(temp);
out.close();
}
public PlayerInfo(String name){
this.name =name;
}
}
if you see it the difference is only separate the Object Input/Output to a method and call them
and I am sorry I am a newbie in this website
I don't know a lot about IO but it seems like I cant separate it to methods and call it?
The problem is that in your first code you (correctly) open an input stream uses it and then closes it before doing anything else to the same file but in your second code version you also open the output stream on the same file before having read it and that output stream puts the marker (where to read or write) at the end of the file so when you use your input stream you get an End of file error.
Changing you code to this should work
openTheInPutObjectStreamer();
initializeHashMap();
openTheOutPutObjectStreamer();
I've pair the code down to the methods I am having a problem, with. It 'seems' to work until I try to load the file again, and it comes up with nothing in it. (I have not fully understood how to clear the ArrayList before performing the 2nd load, but that is for later).
I am sorry if this is hidden somewhere under some other nomenclature I also have not learned yet, but this is a project that is due tomorrow and I am at my wit's end.
import java.util.*;
import java.io.*;
public class MainATM3 {
public static ArrayList<ClientAccount> accounts = new ArrayList<ClientAccount>();
public static ClientAccount editBankAccount = new ClientAccount("placeholder",1234,1);;
public static void main(String[] args) {
// Create ATM account ArrayList
ArrayList<ClientAccount> accounts = new ArrayList<ClientAccount>();
// Get Account data from files
initialLoadATMAccounts(accounts);
System.out.println("Loaded "+accounts.size());
System.out.println("before Array "+(accounts.size()));
accounts.add(0,new ClientAccount("Jess",500,1830));
accounts.add(1,new ClientAccount("Mary",1111.11,7890));
System.out.println("after Array "+(accounts.size()));
saveATMAccounts(accounts);
System.out.println("saved "+(accounts.size()));
initialLoadATMAccounts(accounts);
System.out.println("Loaded "+accounts.size());
System.out.println("Logged Out");
}
// Save ArrayList of ATM Objects //call by: saveATMAccounts(accounts);
public static void saveATMAccounts(ArrayList<ClientAccount> saveAccounts) {
FileOutputStream fout = null;
ObjectOutputStream oos = null;
try{
fout=new FileOutputStream("ATMAccounts.sav");
oos = new ObjectOutputStream(fout);
oos.writeObject(accounts);
System.out.println("objects written "+(accounts.size()));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (fout != null) {
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// INITIAL Load ArrayList of ATM Objects //call by: initialLoadATMAccounts(accounts);
public static void initialLoadATMAccounts(ArrayList<ClientAccount> loadAccounts){
FileInputStream fIS = null;
ObjectInputStream oIS = null;
try{
fIS=new FileInputStream("ATMAccounts.sav");
oIS = new ObjectInputStream(fIS);
ArrayList<ClientAccount> loadAccounts = (ArrayList<ClientAccount>) oIS.readObject();
oIS.close();
fIS.close();
}
catch(Exception exc){
exc.printStackTrace();
}
}
}
import java.io.Serializable;
public class ClientAccount implements Serializable {
public String accountName;
public double accountBalance;
public int accountPIN;
public ClientAccount(String accountName, double accountBalance, int accountPIN){
this.accountName=accountName;
this.accountBalance=accountBalance;
this.accountPIN=accountPIN;
}
// Account Name Methods
public String getAccountName() {
return accountName;
}
public void setAccountName(String name) {
accountName = name;
}
// Account Balance Methods
public double getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(double balance) {
accountBalance = balance;
}
// PIN Methods
public int getAccountPIN() {
return accountPIN;
}
public void setAccountPIN(int newPIN) {
accountPIN = newPIN;
}
}
Instead of passing the desired array to initialLoadATMAccounts as param you should return the new, loaded array:
public static List<ClientAccount> initialLoadATMAccounts(){
FileInputStream fIS = null;
ObjectInputStream oIS = null;
try{
fIS=new FileInputStream("ATMAccounts.sav");
oIS = new ObjectInputStream(fIS);
ArrayList<ClientAccount> loadAccounts = (ArrayList<ClientAccount>) oIS.readObject();
oIS.close();
fIS.close();
return loadAccounts;
}
catch(Exception exc){
exc.printStackTrace();
}
}
BTW: A IDE like eclipse would have issued a warning where you overwrite the param loadAccounts.
I am working on an android project that loads data remotely, saves it into an array (if the data is new), writes it to disk as a serializeable, then reads it from disk to load an ArrayList.
Sometimes the ArrayList populates with the data, sometimes it doesn't and the program crashes.
I receive a runtime exception stating: java.land.ClassCastException: java.lang.String cannot be cast to java.io.ObjectStreamClass.
Sometimes I also receive a java.io.StreamCorruptedException, and sometimes I receive and EOFException.
Going through the exception tree, it seems to be originating from this call:
personsArray = (ArrayList<Person>) in.readObject();
Now, sometimes the data loads fine without issues, most of the time the program crashes.
Here is the code that saves the data to disk:
public static boolean saveFromRemoteSource(Context c, ArrayList<?> source){
//Save context
context = c;
//Save source to local file
File file = context.getFileStreamPath(PERSONS_FILE);
//Status if successful in saving
boolean savedStatus = false;
try {
if(!file.exists()){
file.createNewFile();
}else{
//file already exists so don't do anything
}
//now load the data into the file
FileOutputStream fos = context.openFileOutput(PERSONS_FILE, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(source);
oos.close();
savedStatus = true;
} catch(IOException e){
e.printStackTrace();
savedStatus = false;
}
return savedStatus;
}
Here is the code that reads the data from disk:
public static boolean loadPersonsArray(Context c){
context = c;
boolean loadStatus = false;
File file = context.getFileStreamPath(PERSONS_FILE);
try{
if(!file.exists()){
file.createNewFile();
}else {
//File is already created, do nothing
}
BufferedReader br = new BufferedReader(new FileReader(file));
if (br.readLine() != null) {
FileInputStream fis = context.openFileInput(PERSONS_FILE);
ObjectInputStream in = new ObjectInputStream(fis);
personsArray = (ArrayList<Person>) in.readObject();
in.close();
fis.close();
loadStatus = true;
}
br.close();
} catch(IOException e){
e.printStackTrace();
Log.d("TAG", "IOException PERSONS_FILE file: " + e);
loadStatus = false;
} catch (ClassNotFoundException e) {
e.printStackTrace();
Log.d("TAG", "ClassNotFoundException PERSONS_FILE file classnotfound: " + e);
}
return loadStatus;
}
This is the Person class:
import java.io.Serializable;
public class Person implements Serializable, Comparable<Person>{
//Person class
private static final long serialVersionUID = 1L;
private String personID;
private String personName;
private boolean displayPerson;
//default constructor
public Person(){
super();
}
public Person(String personID,
String personName,
boolean displayPerson){
super();
this.personID = personID;
this.personName = personName;
this.displayPerson = displayPerson;
}
//Accessor Methods
public String getPersonID(){
return personID;
}
public String getPersonName(){
return personName;
}
public boolean getDisplayPerson(){
return displayPerson;
}
//setter methods
public void setPersonID(String personID){
this.personID = personID;
}
public void setPersonName(String personName){
this.personName = personName;
}
public void setDisplayPerson(boolean displayPerson){
this.displayPerson = displayPerson;
}
#Override
public String toString(){
return this.getPersonName().replaceAll("[^A-Za-z0-9]", "") + this.getDisplayPerson();
}
public int compareTo(Person otherPerson) {
if(!(otherPerson instanceof Person)){
throw new ClassCastException("Not a valid Person object!");
}
Person tempPerson = (Person)otherPerson;
if(this.getPersonName().compareToIgnoreCase(tempPerson.getPersonName()) > 0){
return 1;
}else if(this.getPersonName().compareToIgnoreCase(tempPerson.getPersonName()) < 0){
return -1;
}else{
return 0;
}
}
}
Where the data comes from to be written to the file
private void downloadPersons(){
HashMap<String, String> params = new HashMap<String, String>();
Kumulos.call("selectAllPersons", params, new ResponseHandler() {
#Override
public void didCompleteWithResult(Object result) {
ArrayList<Object> personsList = new ArrayList<Object>();
for(Object o : (ArrayList<?>)result){
Person person = new Person();
person.setPersonID(replaceNandT((String) ((HashMap<?,?>) o).get("personID")));
person.setLawName(replaceNandT((String) ((HashMap<?,?>) o).get("personName")));
person.setDisplayLaw(stringToBool((String)((HashMap<?,?>) o).get("displayPerson")));
if(person.getDisplayPerson()==true){
personsList.add(person);
}
}
//Save personsList to a file
if(PersonsLoader.saveFromRemoteSource(context, personsList)){
updateVersionNumber();
isFinished=true;
Log.d("TAG", "PersonsLoader.saveFromRemoteSource(context, personsList) success");
}
}
});
}
So what do you think is happening at this call?
Get rid of both the blocks that test File.exists(), and the File.createNewFile() calls.
Opening the file for output will create it if necessary.
When opening the file for reading, if the file doesn't exist a FileNotFoundException will be thrown. There's no point in creating an empty file to avert this: it just leads to other problems.
And get rid of the BufferedReader and readLine() calls too. They serve no useful purpose. There are no lines in an object output stream.
This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 5 years ago.
`I am new to java and getting StreamCorruptedException in the code below... In this code I am trying to read multiple objects from a file using ObjectInputStream... m not able to handle the StreamCorruptedException...the o/p I m getting is
File C098.txt already exists
Product ID:- P001
Description:- Book
Price:- Rs.200
Exception in thread "main" java.io.StreamCorruptedException: invalid type code:
AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1374)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Utility.getProducts(Utility.java:57)
at Utility.main(Utility.java:23)
CODE:
import java.io.*;
import java.util.*;
class Product implements Serializable{
private static final long serialVersionUID = 1L;
String productId;
String desc;
String price;
public Product(String PId,String a_des,String a_price){
productId=PId;
desc=a_des;
price=a_price;
}
public String toString(){
return "Product ID:- "+productId+"\nDescription:- "+desc+"\nPrice:- "+price;
}
}
class Utility{
// Product objProduct;
public static void main(String args[]) throws Exception{
String cartId = "C098.txt";
Product objProduct = new Product("P001","Book","Rs.200");
addProductToCart(cartId,objProduct);
getProducts(cartId);
objProduct = new Product("P087","Laptop","Rs.45,500");
addProductToCart("C098.txt",objProduct);
getProducts(cartId);
}
public static void addProductToCart(String CId,Product p) throws Exception{
try{
boolean searchFile;
File objFile = new File(CId);
searchFile = objFile.exists();
if(searchFile)
System.out.println("File "+CId+" already exists");
else{
objFile.createNewFile();
System.out.println("File "+CId+" did not exist. It is now created");
}
FileOutputStream objFOS = new FileOutputStream(objFile,true);
ObjectOutputStream objO = new ObjectOutputStream(objFOS);
objO.writeObject(p);
objO.flush();
objO.close();
}catch(Exception e)
{
System.out.println("Exception Caught");
}
}
public static void getProducts(String CId) throws Exception{
Product objProduct1 = new Product("","","");
File objFile1 = new File(CId);
FileInputStream objFIS = new FileInputStream(objFile1);
ObjectInputStream objI = new ObjectInputStream(objFIS);
Object obj = null;
try{
while((obj=objI.readObject()) != null){
if (obj instanceof Product) {
System.out.println(((Product)obj).toString());
}
}
}catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
}finally {
//Close the ObjectInputStream
try{
if (objI != null)
objI.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}`
The problem is because of header issue, You are appending to same file and while returning second object it throws exception because of headers issue. try to write object in different files, you can rid out of the problem.
SCE Thrown when control information that was read from an object stream violates internal consistency checks.
try
import java.io.*;
import java.util.*;
class Product implements Serializable{
private static final long serialVersionUID = 1L;
String productId;
String desc;
String price;
public Product(String PId,String a_des,String a_price){
productId=PId;
desc=a_des;
price=a_price;
}
public String toString(){
return "Product ID:- "+productId+"\nDescription:- "+desc+"\nPrice:- "+price;
}
// Product objProduct;
public static void main(String args[]) throws Exception{
String cartId = "C0982.txt";
Product objProduct = new Product("P001","Book","Rs.200");
addProductToCart(cartId,objProduct);
getProducts(cartId);
Product objProduct1 = new Product("P087","Laptop","Rs.45,500");
addProductToCart("C0981.txt",objProduct1);
getProducts("C0981.txt");
}
public static void addProductToCart(String CId,Product p) throws Exception{
try{
boolean searchFile;
File objFile = new File(CId);
searchFile = objFile.exists();
if(searchFile)
System.out.println("File "+CId+" already exists");
else{
objFile.createNewFile();
System.out.println("File "+CId+" did not exist. It is now created");
}
FileOutputStream objFOS = new FileOutputStream(objFile,true);
ObjectOutputStream objO = new ObjectOutputStream(objFOS);
objO.writeObject(p);
objO.flush();
objO.close();
}catch(Exception e)
{
System.out.println("Exception Caught");
}
}
public static void getProducts(String CId) throws Exception{
Product objProduct1 = new Product("","","");
File objFile1 = new File(CId);
FileInputStream objFIS = new FileInputStream(objFile1);
ObjectInputStream objI = new ObjectInputStream(objFIS);
Object obj = null;
try{
while((obj=objI.readObject()) != null){
if (obj instanceof Product) {
System.out.println(((Product)obj).toString());
}
}
}catch (EOFException ex) { //This exception will be caught when EOF is reached
System.out.println("End of file reached.");
}finally {
//Close the ObjectInputStream
try{
if (objI != null)
objI.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
</pre>
You can't 'handle' it. You have to prevent it. It results from a design error such as using two ObjectOutputStreams on a stream that is read by a single ObjectInputStream, as you are doing here by appending to the file, or writing data other than objects and not reading it symmetrically.