Load/Store Objects in file in Java - java

I want to store an object from my class in file, and after that to be able to load the object from this file. But somewhere I am making a mistake(s) and cannot figure out where. May I receive some help?
public class GameManagerSystem implements GameManager, Serializable {
private static final long serialVersionUID = -5966618586666474164L;
HashMap<Game, GameStatus> games;
HashMap<Ticket, ArrayList<Object>> baggage;
HashSet<Ticket> bookedTickets;
Place place;
public GameManagerSystem(Place place) {
super();
this.games = new HashMap<Game, GameStatus>();
this.baggage = new HashMap<Ticket, ArrayList<Object>>();
this.bookedTickets = new HashSet<Ticket>();
this.place = place;
}
public static GameManager createManagerSystem(Game at) {
return new GameManagerSystem(at);
}
public boolean store(File f) {
try {
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(games);
oos.writeObject(bookedTickets);
oos.writeObject(baggage);
oos.close();
fos.close();
} catch (IOException ex) {
return false;
}
return true;
}
public boolean load(File f) {
try {
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
this.games = (HashMap<Game,GameStatus>)ois.readObject();
this.bookedTickets = (HashSet<Ticket>)ois.readObject();
this.baggage = (HashMap<Ticket,ArrayList<Object>>)ois.readObject();
ois.close();
fis.close();
} catch (IOException e) {
return false;
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
.
.
.
}
public class JUnitDemo {
GameManager manager;
#Before
public void setUp() {
manager = GameManagerSystem.createManagerSystem(Place.ENG);
}
#Test
public void testStore() {
Game g = new Game(new Date(), Teams.LIONS, Teams.SHARKS);
manager.registerGame(g);
File file = new File("file.ser");
assertTrue(airport.store(file));
}
}

The solution of this problem is that when you are using other objects, let say class A, into a collection like HashMap and want to serialize the HashMap object, then implement the interface Serializable for class A like this:
class A implements Serializable {
}
...
HashMap<Integer,A> hmap;
...
Otherwise that object will not be serializable.
I hope it will solve this problem now.

Try oos.flush() before you close it.

Please remenber that the whole object graph is persisted during serialize. If you have some references to GUI classes for example, you either have to make them serializable, too, or tag them as "transient", so Java won't serialize them.

Related

Java read a file into an arraylist of objects and return that arraylist

I need to write a class that has two static methods: writeFile and readFile. However, after I do my readFile(), it returns nothing.
class writereadFile {
public static void writeFile(ArrayList<Object> list, File file){
try {
try (FileOutputStream fos = new FileOutputStream(file);ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(list);
oos.close();
}
}catch(IOException e){e.getMessage();}
}
public static ArrayList<Object> readFile(ArrayList<Object>list, File file){
try {
try (FileInputStream fis = new FileInputStream(file);ObjectInputStream ois = new ObjectInputStream(fis)) {
Object o = ois.readObject();
list = (ArrayList<Object>) o;
ois.close();
}
}catch(IOException | ClassNotFoundException e){e.getMessage();}
System.out.println(list);
return list;
}
}
EDIT:
This my class for testing. My object is an arraylist of custom objects if you need the custom object just comment.
class main {
public static void main(String[] args) {
Date date = new Date();
Book b1 = new Book("abc", "Phi", true, date, null);
Book b2 = new Book("cba", "Someone", true, date, null);
Books booklist = new Books();
booklist.add(b1);
booklist.add(b2);
File filetoDo = new File("book.txt");
//write arraylist into file
writereadFile.writeFile(booklist, filetoDo);
//clear the arraylist
booklist.clear();
//read book from file
writereadFile.readFile(booklist, filetoDo);
System.out.println(booklist);
}
}
Your test should read:
bookList = writereadFile.readFile(booklist, filetoDo);
and, by the way, you should really refactor your readFile method to simply:
public static ArrayList<Object> readFile(File file)
You can't modify the argument reference like that, since Java is always pass-by-value call semantics. (You could modify the list argument contents inside the function, but that's not what you are doing.)
If you are using Java 8 try using Streams:
public static readFile(String filePath) {
List<Object> list = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
stream.forEach(list::add);
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
I'm playing around this topic a bit on my own, so below you can find some code snippets that might help you.
Examples are very short and simple, so I hope you will not just use e.printStackTrace() in your code :)
public class ExternalIO {
private ExternalIO() {
}
public static ObjectOutputStream objectOutputStream(String basePath, String pathToFile) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream(createFileIfDoesNotExist(absolutePath(basePath, pathToFile)));
return new ObjectOutputStream(fileOutputStream);
}
public static ObjectInputStream objectInputStream(String basePath, String pathToFile) throws IOException {
FileInputStream fileInputStream = new FileInputStream(absolutePath(basePath, pathToFile));
return new ObjectInputStream(fileInputStream);
}
private static File createFileIfDoesNotExist(String absolutePath) throws IOException {
File file = new File(absolutePath);
if (file.exists()) {
return file;
}
file.getParentFile().mkdirs();
file.createNewFile();
return file;
}
private static String absolutePath(String basePath, String pathToFile) {
return Paths.get(basePath, pathToFile).toAbsolutePath().toString();
}
}
output usage:
List<ItemType> input = null; //create your input list here
try (ObjectOutputStream objectOutputStream = ExternalIO.objectOutputStream(CONFIG, FILENAME)) {
objectOutputStream.writeObject(input);
} catch (Exception e) {
e.printStackTrace();
}
input usage:
try (ObjectInputStream objectInputStream = ExternalIO.objectInputStream(CONFIG, FILENAME)) {
return (List<ItemType>) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
hope that helps ; )

Cloning data between two objects with a field sorted set Java

Ok so i have two classes: Content and TrackUserChanges . They have the same fields.
public class Content{
private Long id;
......
private SortedSet<Content> children = new TreeSet<Content>();
}
public class TrackUserChanges{
private Long id;
.....
private SortedSet<Content> children = new TreeSet<Content>();
}
I want to clone the data from Content to TrackUserChanges:
I have the children from an instance of content:
SortedSet<Content> children = content.getChildren();
This can contain many other contents, and that contents can have also children, etc.
SortedSet<TrackUserChanges> children1 = convertContentSetToTrackUserChangesSet(children);
This is the method:
public SortedSet<TrackUserChanges> convertContentSetToTrackUserChangesSet(SortedSet<Content> children){
SortedSet<TrackUserChanges> children1 = new TreeSet<TrackUserChanges>();
for(Content c : children){
TrackUserChanges trackU = new TrackUserChanges();
trackU.setCategory(c.getCategory());
trackU.setId(c.getId());
trackU.setBook(c.getBook());
trackU.setInsertUser(c.getInsertUser());
trackU.setParent(c.getParent());
trackU.setParentId(c.getParentId());
trackU.setRelativeSortOrder(c.getRelativeSortOrder());
trackU.setText(c.getText());
trackU.setType(c.getType());
children1.add(trackU);
}
return children1;
}
I need somehow to call recusively or something like that... and I can't do trackU.setChildren(c.getChildren()) because the types don't match :/
#Mifmif
try {
FileOutputStream fout = new FileOutputStream("a.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(content);
oos.close();
}
catch (Exception e) { e.printStackTrace(); }
TrackUserChanges trackUserChanges11 = new TrackUserChanges();
try {
FileInputStream fin = new FileInputStream("a.dat");
MyCustomObjectInputStream custom = new MyCustomObjectInputStream(fin);
// custom.readClassDescriptor();
trackUserChanges11 = (TrackUserChanges) custom.readObject();
System.out.println("IDDDDD" + trackUserChanges11.getId());
custom.close();
}
catch (Exception e) { e.printStackTrace(); }
ClassCastException :)
If you have two classes with identical properties that have identical behaviour, separate those fields/behaviour into a separate class and extend that class in your other classes. This should allow you to copy directly between them.
Make your class implements Cloneable. Then just call the function clone of the SortedSet.
http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html
Here is a solution based on serialization , make both of your class serializable and if you want to go from one class instance to another, serialize your instance into a file , and read it using MyCustomObjectInputStream :
class MyCustomObjectInputStream extends ObjectInputStream {
public MyCustomObjectInputStream(InputStream in) throws IOException {
super(in);
}
#Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
if (resultClassDescriptor.getName().equals("name.of.the.package.OldClassName"))
resultClassDescriptor = ObjectStreamClass.lookup(name.of.the.package.NewClassName.class);
return resultClassDescriptor;
}
}
I resolved the problem
public TrackUserChanges convertContentToTrack(Content c) {
TrackUserChanges t = new TrackUserChanges();
t.setCategory(c.getCategory());
t.setId(c.getId());
t.setBook(c.getBook());
t.setInsertUser(c.getInsertUser());
t.setParent(c.getParent());
t.setParentId(c.getParentId());
t.setRelativeSortOrder(c.getRelativeSortOrder());
t.setText(c.getText());
t.setType(c.getType());
if (c.getChildren().size() == 0) {
return t;
}
SortedSet<TrackUserChanges> childs = new TreeSet<TrackUserChanges>();
for (Content content : c.getChildren()) {
childs.add(convertContentToTrack(content));
}
t.setChildren(childs);
return t;
}
Thanks anyway :)

Java ClassCastException while using FileInputStream

I am trying to save/load instances of my TicketSet class in Java. Below is the class and the class variables. The Ticket and Variable class are also Serializable.
public class TicketSet implements Serializable{
public final int setID;
public int ticketNum;
public Ticket[] tickets;
private static int xCount[];
private static int yCount[];
private static int zCount[];
private Variable x;
private Variable y;
private Variable z;
In another class I save an instance of the TicketSet class which seems to work fine. In the code, gen is just an instance of a controller class which initialises TicketSet.
TicketSet set;
if (f.exists()) {
FileOutputStream fileOut =new FileOutputStream(f,true);
AppendingObjectOutputStream out = new AppendingObjectOutputStream(fileOut);
set = gen.getTSet();
out.writeObject(set);
out.close();
fileOut.close();
} else {
FileOutputStream fileOut =new FileOutputStream(f,true);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
set = gen.getTSet();
out.writeObject(set);
out.close();
fileOut.close();
}
To load the instances of TicketSet, I have the following code which throws the error.
ArrayList<Integer> tickid = new ArrayList<Integer>();
tSets = new HashMap<Integer, TicketSet>();
FileInputStream fileStr = null;
ObjectInputStream reader = null;
try {
fileStr = new FileInputStream("TicketSets.ser");
reader = new ObjectInputStream(fileStr);
System.out.println(fileStr.available());
TicketSet tSet= null;
while (fileStr.available()>0) {
Object next = reader.readObject(); //ERROR HERE
if (next instanceof TicketSet) {
tSet = (TicketSet) next;
System.out.println("ID: "+tSet.setID);
tSets.put(tSet.setID, tSet);
tickid.add(tSet.setID);
} else {
System.out.println("Unexpected object type: " + next.getClass().getName());
}
}
//System.out.println("Size: "+tSets.size());
reader.close();
fileStr.close();
}
catch(IOException i) {
i.printStackTrace();
}
catch (ClassNotFoundException c) {
System.out.println("TicketSet class not found");
c.printStackTrace();
}
The error thrown is:
ID: 7325825
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.io.ObjectStreamClass
So what I understand is:
The first TicketSet is loaded fine... which has ID=73225825
It is then trying to load an integer from the file rather than a TicketSet object.
Why is it trying to load an integer? Is there a way to skip reading anything other than objects? Should I try an alternative approach?
I was missing the Reset() in my AppendingObjectOutputStream.
ClassCastException when Appending Object OutputStream

Replacement for Marker Interface and Annotation

This thing come to my mind when I implemented custom Marker Interface. As the Serializable Marker interface is used for Serialization in java, I made my own Marker Interface to set a flag at class level.
public class MIOne implements Serializable,MarkerInterface{
private int one;
private String str;
public MIOne() {
super();
this.one = 1;
this.str = "MIOne";
}
Object writeObject() throws IOException {
if (!(this instanceof MarkerInterface)) {
FileOutputStream out = new FileOutputStream("D:\\testTransients.ser");
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(this);
} else {
System.out.println("Unable to Support Searialization");
}
return null;
}
Object readObject() throws IOException, ClassNotFoundException {
if (!(this instanceof MarkerInterface)) {
FileInputStream fis = new FileInputStream("D:\\testTransients.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
MIOne c = (MIOne) ois.readObject();
} else {
System.out.println("Unable to Support Searialization");
}
return null;
}
}
But in this I have to make a blank Interface, than implement my logic accordingly (using instanceOf operator). I need your help to sort the same problem with some other better and simpler solution. Is that possible?

ObjectInputStream[Java]

i'm new to file i/o so i'm sorry if this is a pretty bad question.
Currently I have an add method/main method and a person class my outputstream is working fine in the add method: This is at the top of the method
FileOutputStream myFile = null;
try {
myFile = new FileOutputStream("txt123.txt");
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(myFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
And I then have this twice because there are two types of people that can be added
oos.writeObject(person);
oos.close();
System.out.println("Done");
So my question, how do i get the input working and finally where do i put it, in the add method or the main method, I read how to do what i done here: http://www.mkyong.com/java/how-to-write-an-object-to-file-in-java/
He also has a guide on reading in the objects but I cant seem to get it working
Thanks!
You would be reading the file you just created like this:
ObjectInputStream in =
new ObjectInputStream(new FileInputStream("txt123.txt"));
// terrible file name, because this is binary data, not text
try{
Person person = (Person) in.readObject();
finally{
in.close();
}
You can combine the ObjectOutputStream with the FileOutputStream as follows. I'm also guessing you need to place the read/write code in one place to allow re-use. Here's a simple example with the read/write in a DAO.
public static class Person implements Serializable {
private String name;
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
}
public static class PersonDao {
public void write(Person person, File file) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
oos.writeObject(person);
oos.close();
}
public Person read(File file) throws IOException,
ClassNotFoundException {
ObjectInputStream oos = new ObjectInputStream(new FileInputStream(
file));
Person returnValue = (Person) oos.readObject();
oos.close();
return returnValue;
}
}
public static void main(String[] args) throws IOException,
ClassNotFoundException {
PersonDao personDao = new PersonDao();
Person alice = new Person("alice");
personDao.write(alice, new File("alice.bin"));
Person bob = new Person("bob");
personDao.write(bob, new File("bob.bin"));
System.out.println(personDao.read(new File("alice.bin")));
System.out.println(personDao.read(new File("bob.bin")));
}

Categories

Resources