Storing complex object to a file in android application - java

FileOutputStream fout = context.getApplicationContext()
.openFileOutput(FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fout);
out.writeObject(complexObject);
Will this code work for a complexObject which is an instance of a complex class. By complex I mean that it might contain several arraylists of instances of other classes, many instance variables?

Yes, ObjectOutputStream can serialize a complex tree of objects as long as all objects in this tree implement Serializable. It also serializes all java primitive types.

Related

Saving data structures in Java

Please give me some advice regarding data saving in Java.
I’m new in Java. Previously I wrote programs on C++.
It was easy to save data in C++: just declare structure, fill its fields and then save it like byte array. As far as Java doesn’t have structures I suppose that Java programming means another save concept.
I will appreciate you for ideas and ideas what to read regarding this.
It's simpler in Java.
Use a class in place of your C++ struct, and implement java.io.Serializable. Your IDE will help you build any methods that you need to implement. Conceptually Java uses reflection to capture the values of the fields (aside from ones you've marked Transient) in your class, so, by and large, the process is automated.
I am guessing, by 'saving' you mean saving to a disc.
If that is the case, you should be looking at the concept of serialization in Java.
Make your class implement the Serializable interface.
Then take cue from the following code to serialize.
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
Code on similar lines to deserialize.
In java instead of structure create a class corresponding to your storage criteria then create object for that class and then you can store the required datas in that object then store that object in array or any collections.
for eg create Student class which has name,regno etc.. then create object of student class store the datas in that object,so you can have your data in an object which is similar to structure then you can save students object in array or collections.

Is it recommended to serialize & deserialize objects that are stored in arrayList?

In my small bank application, users have to input some value (name, SSN, amount etc..) and they get stored in an arrayList. The arrayList size is dynamic.
But problem with this one is I loose all data once I terminate the application. That leads me to think about the implementation of writing and reading file (file I/O).
Now I also have come to know about something called serialization and deserialization, though I am not quite sure in what situation this need to be implemented.
Do I need it in my particular case or simply writing into and reading from file will be enough?
What serialization and deserialization has to do with file I/O?
[NOTE: I will give more info if necessary]
This is where a Database comes into picture. To start with, you can use MySQL DB - it' an excellent FREE Database for small to medium size business apps. Later, if you intend to deploy your app to production - with large number of users & advance features, and are ready to pay a price for it - you might consider other databases like Oracle etc.
Storing info to files ((De)Serialization) is not recommended for any practical application.
Serialization is a mechanism where an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
ArrayList already implements Serializable, so in your example you could write something like this:
ArrayList<String> al=new ArrayList<String>();
al.add("Jean");
al.add("Pierre");
al.add("John");
try{
FileOutputStream fos= new FileOutputStream("myfile.txt");
ObjectOutputStream oos= new ObjectOutputStream(fos);
oos.writeObject(al);
oos.close();
fos.close();
}catch(IOException ioe){
ioe.printStackTrace();
}
Here we save the list al in the file myfile.txt.
To read the file and get your ArrayList back, you would use ObjectInputStream:
FileInputStream fis = new FileInputStream("myfile.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
ArrayList<String> list = (ArrayList<String>) ois.readObject();
ois.close();
Serialization is required when you want to write instances of your own class to a file. In your case, you can create a java class to hold all the values about customer, then override hashCode() and equals(), and then write your object to file. http://www.tutorialspoint.com/java/java_serialization.htm
Also, if you want, you can store individual field in file as well as int or String.
Though I would suggest to use a database to store all this information. But it seems you are a student and still in learning phase. So, interacting with DB right away might not be a good approach as of now.
Yes, you can use arraylist for serialization and deserialization.
Whenever u want to write and read the object into file and from file
respectively then u need to be object should be serialized and object
write into the file in byte stream format.that means ur data will be secure in
stream.you can used serialization interface:-
To persist data for future use.
To send data to a remote computer using such client/server Java technologies as RMI or socket programming.
To "flatten" an object into array of bytes in memory.
To exchange data between applets and servlets.
To store user session in Web applications.
To activate/passivate enterprise java beans.
To send objects between the servers in a cluster.
and more............

Serialize a hierarchical structure of objects in java

I have an abstract class Screen and child classes: GameScreen, SpellScreen, StatsScreen, etc.
The game works in this way: a Renderer class creates a root
Screen screenRoot = new GameScreen()
which then is free to add screens to itself, which then may add screens to themselves and so it goes. Therefore a tree-like structure is formed, every Screen containing a list of its child-screens.
Now I am wondering if it's possible to perform serialization and deserialization on that - I'd like to recreate all the screens in the same hierarchy.
Is it enough to serialize only the screenRoot object, and then deserialize it (provided I want to preserve the whole screens tree), or do I need to traverse the tree myself somehow?
How would you go about serializing this?
P.S. the game is for Android and uses OpenGL ES 2.0.
A hierarchy of objects is no impediment to using Java Serialization, as the latter can cope with arbitrary object graphs - and yes, serializing an object using Java Serialization will serialize all objects it refers to (unless that reference is marked transient). Assuming that's what you want, serializing the hierarchy is as simple as:
try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename)))) {
oos.write(rootScreen);
}
and reading as simple as:
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)))) {
return (GameScreen) ois.readObject();
}
There are two issues here.
First, screens should be just that--screens. They shouldn't contain the "model" or object data that represents your game state; only the view/rendering of that state. So serializing and deserializing, doesn't really make sense. I would suggest looking at your architecture again to see if this is really what you want to do.
If you decide to do it, or if you have another game-state object root that you can serialize (I usually use the Player since it has all the essential data in it), you can easily do this with Gson:
// Save
RootObject o = ...; // The root of the hierarchy to serialize
Gson gson = new Gson();
String serialized - gson.toJson(o); // JSON object, eg. { "Player": { ... } }
// Load
RootObject deserialized = gson.fromJson(serialized, RootObject.class);
You can read more in their user guide.
Second, on the issue of JSON and Gson: I prefer this over standard serialization, because it's robust in the face of changes. If your class definitions change, you can still deserialize objects (albeit you get null/empty fields) instead of a runtime exception; you don't need to worry about versioning your classes, either.
Edit: questions like this are better suited to the Game Dev SE site.

Save java object tree with versioning?

I have a Java application which saves a object tree to file using default java object serialization (ObjectOutputStream and such). This works quite nicely.
The problem arises when I add a field to an object that is in the object tree. When I now load the old object tree I get a ClassException, which of course makes sense cause that object/class changed and the old class doesn't match the new class.
Now I can write different versions of my load method so that it can handle old object trees, but I suspect this might become not very easy to manage and maintain.
I was wondering if there is a better way to save a object tree in java which supports versioning?
You can use this approach (implementing readObject and writeObject) to handle schema migration: http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-control.html
use the readObject()
and writeObject()
methods of ObjectInputStream and ObjectOutputStream class in your Serializable class
in order to define the default behavior when serializing/deserializing the object from
your file
ObjectOutputStream oos = new ObjectOutputStream(file/path/url);
oos.writeObject(serialized Object);
oos.close();
oos.flush();
ObjectInputStream ois = new ObjectInputStream(file/path/url/request);
Object obj = (TypeCast to appropriate Object)ois.readObject();

Why should i use Serialization instead of File I/O in java

In serialization mechanism,we are wrote the object into stream using objectinputstream and object outputstream.These objects passing across the network.In this mechanismusing a Object input/output stream.So Can i use File INPUT/OUTPUT Streams instead of calling serialization marker interface?.
I guess You are mixing up serialization and general I/O.
Serialization is a way to transform objects into byte sequences (and back, which is called Deserialization). This way, You can transmit serializable objects over the network and store them into files.
File input/output streams are for storing/reading any kind of data to/from files.
when you need to transfer your object on network, you need to serialized it. Below link might be useful for you.
http://java.sun.com/developer/technicalArticles/Programming/serialization/
File I/O and Serialization are two different things. File I/O is used to read/write a file. Serialization interface is used for binary interpretation of an object. So NO, you can't use File Streams for sending over network.(maybe there is some workaround for sending data over network using file streams, but its like trying to fly with a car)
First let's concentrate on the definition:
Serialization: It is the process of converting object state into a format that can be stored and reconstructed later in the same way.
Whereas in file I/O it can't be possible to store data-structure or object and reconstructed later in the same way.
That's why we use serialization or database query methods (like sql, mongodb).
JSON/XML can also be used for serialization using its parser.
Take an example of javascript (not java, but take it like language-agnostics):
var obj = { // it's an object in javascript (same like json)
a: "something",
b: 3,
c: "another"
};
Now if you try to use file i/o in this to save in a file (say abc.txt), it will be saved as a string
which means it can't be accessed later in other code by reading this file (abc.txt) like this:
// readThisFile();
// obj.a;
But if you use serialization (in javascript using JSON natively), you can read it from the file
Since streams are additive, you can do something like
FileOutputStream fos = new FileOutputStream("/some/file/to/write/to");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(someObject);
Not sure this is what you were asking, but it's hard to tell.
Serialization/Deserialization is used to read and write objects, which not only makes compressed data, which is unreadable but also is writes it in binary. The File I/O is used for reading and writing. It appears that you do not want to serialize, if you don't, well do not use it. Read and write your files in text.
In serialization mechanism,we write the object into s stream using
ObjectInputStream and ObjectOutputStream.
Ok
These objects are passed across the network.In this mechanism using a
ObjectInput/Output stream.
I am following you.
So can I use File Input/Output streams instead of calling
serialization marker interface?.
Here you lost me. Do you mean to send an object over the network or just to serialize it?
Of course you can use whichever Input/Output streams along with ObjectInput/ObjectOutput streams to serialize objects to different media.
For instance:
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("jedis.bin"));
out.writeObject(new Jedi("Luke"));
Would serialize the object into a file called jedis.bin
And the code
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOputStream out = new ObjectOutputStream(byteStream);
out.writeObject(new Jedi("Luke"));
Would serialize the object into a memory array.
So, anything that is an output/input stream is subject of being used as the underlying stream used by ObjectInput/ObjectOutput streams.

Categories