Java: Writing/Reading a Map from disk - java

I have a data structure that I would like to be able to write to a file before closing the program, and then read from the file to re-populate the structure the next time the application starts.
My structure is HashMap<String, Object>. The Object is pretty simple; For member variables it has a String, and two small native arrays of type Boolean. This is a real simple application, and I wouldn't expect more than 10-15 <key,value> pairs at one time.
I have been experimenting (unsuccessfully) with Object input/output streams. Do I need to make the Object class Serializable?
Can you give me any suggestions on the best way to do this? I just need a push in the right direction. Thanks!
EDIT: Well I feel dumb still, I was writing from one map and reading into another map, and then comparing them to check my results. Apparently I was comparing them wrong. Sigh.

If you aren't concerned about Object particularly , you just need key value pair of String,String then I would suggest you to go for java.util.Properties. otherwise here you go
Map map = new HashMap();
map.put("1",new Integer(1));
map.put("2",new Integer(2));
map.put("3",new Integer(3));
FileOutputStream fos = new FileOutputStream("map.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(map);
oos.close();
FileInputStream fis = new FileInputStream("map.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Map anotherMap = (Map) ois.readObject();
ois.close();
System.out.println(anotherMap);

Map m = new HashMap();
// let's use untyped and autoboxing just for example
m.put("One",1);
m.put("Two",2);
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("foo.ser")
);
oos.writeObject(m);
oos.flush();
oos.close();

Yes, your objects will need to implement Serializable in order to be serialized by the default Java mechanism. HashMap and String already implement this interface and thus can be serialized successfully.
Take a look at Sun's own Serialization tutorial - it's quite short and I think should cover everything you need for your simple case. (You should just be able to serialise the Map object to the stream, and then read it back in on subsequent runs).
If you do run into problems, try serializing a simple HashMap<String, String> with some dummy values. If this succeeds, you'll know that the problem lies (somehow) with your own class' serializability; alternatively, if this doesn't work you can focus on the basic structure before throwing your own class into the mix.
Post back if you have any more specific problems that you can't figure out on your own.

Yes, if you want to write an object to the file system, that object must implement Serializeable. Here is a tutorial that should help you out.

Don't bother with making it Serializable until you understand more about what that's used for. You want to look at FileWriter and google "java file io" A good way to write this data is as CSV.
eg.
key1,key2,key3
valuea1,valuea2,valuea3
valueb1,valueb2,valueb3
Hope this helps.

SERIALIZE A HASHMAP:
This code is working fine , I have implemented and used in my app. Plz make ur functions accordingly for saving map and retrieving map.
Imp thing is, you need to make confirm that the objects you are putting as value in map must be serializable , means they should implement serailizbele interface. ex.
Map<.String,String> hashmap=new HashMap<.String,String>().. here in this line ...map and string both are implictly serializable , so we dont need to implement serializble for these explicitly but if you put your own object that must be serializable.
public static void main(String arr[])
{
Map<String,String> hashmap=new HashMap<String,String>();
hashmap.put("key1","value1");
hashmap.put("key2","value2");
hashmap.put("key3","value3");
hashmap.put("key4","value4");
FileOutputStream fos;
try {
fos = new FileOutputStream("c://list.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(hashmap);
oos.close();
FileInputStream fis = new FileInputStream("c://list.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Map<String,String> anotherList = (Map<String,String>) ois.readObject();
ois.close();
System.out.println(anotherList);
} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
} catch (ClassNotFoundException e) {e.printStackTrace();
}
}

I'd advise against using Serializable; it is much harder to do properly than it first seems. It would seem that simply adding implements Serializable is all you need to do. But in fact this adds many restrictions on your code that are difficult to deal with in practical software development (rather than in school). To see just how horrible these restrictions are, see the book Effective Java (second edition) by Bloch.

Related

How can i load a class that is not found when reading object from ObjectInputStream

How can i load a class that is not found when reading object from ObjectInputStream
Example
InputStream pis = new InputStream();
ObjectInputStream ois = new ObjectInputStream(pis);
Object o = null;
try{
o = ois.readObject();
}
catch(ClassNotFoundException ex){
//How to try to load a class to read object again?????
o = ois.readObject();
}
Thanks,
TH
The classes of the objects you try to deserialize should already be on your classpath when trying to deserialize objects.
If you encounter this, I guess you can't really do much at runtime. Instead you can use this to detect if you are still missing classes from your classpath, and add those to your project and classpath during developing.
Use an RMIClassLoader at both ends, and pay attention to its documented requirements at the sending end.
The ClassNotFoundException could also be thrown if the class has moved.
Let's say you serialize a class instance. Later, the class is moved, due to some refactoring. Then you are stuck as the old class fully qualified name is not longer valid. No way to get your object back from the stream.

Does NIO deliver advantages even on consuming small serialized Stream from /dev/shm?

E.g. There is some app (outside of my src control) that produces thousands and thousands of serialized Map instances stored as /dev/shm/{some Map-ID}.ser . They are serialized using the plain old java.io.* package.
Can the code here, which is within my src control (to de-serialize Map instances), benefit from using NIO instead of plain old java.io.* package? Or, theoretically, given that these IO operations are on /dev/shm, is any NIO advantage presumed to be negligible?
private Map<Integer,String> deserializeMapFrKernelSHM(String shmKey) {
Map<Integer,String> retM = null;
try {
FileInputStream frKernelSHM = new FileInputStream("/dev/shm/"+shmKey+".ser");
ObjectInputStream in = new ObjectInputStream(frKernelSHM);
retM = (Map<Integer,String>) in.readObject();
System.out.println("Linux IPC shmop(GET) de-serialized Map<K,V> from /dev/shm/"+shmKey+".ser");
}catch (Exception e) {
e.printStackTrace();
}
return(retM);
}
Not really. It's almost impossible to combine Object Serialization with NIO.
You could try a BufferedInputStream around the FileInputStream.

How to write map collection on file and read it?

I want to make collection with file paths and statue of each file then save it in file
and read it again when i need to that in java and what best collection type to this.
type of status boolian lock or unlock
Use the Properties object, as you can use the string based save and load.
Since the status is a boolean the following would work:
Map<File,Boolean> status = new HashMap<File,Boolean>();
Since File, HashMap and Boolean all implement Serializable you can write the map to a file using an ObjectOutputStream and read it back with an ObjectInputStream:
FileOutputStream fos = new FileOutputStream("status.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(status);
oos.close();
If the status becomes more complex then be sure use a class that implements Serializable or if it's a custom class implement Serializable yourself.

Saving an array of objects in java for later use in another program

Okay, so my issue is that i have alot of programs that i am using in java that use the exact same array of objects but i dont want to keep recreating this array every time that i write a new program. Is there a way to save an array of objects for use in other java programs. if so how?
If you are a beginner you should serialize the array of objects into a file. The convention is to name your serialized file name-of-file.ser
try
{
FileOutputStream fileOut = new FileOutputStream("card.ser");//creates a card serial file in output stream
ObjectOutputStream out = new ObjectOutputStream(fileOut);//routs an object into the output stream.
out.writeObject(array);// we designate our array of cards to be routed
out.close();// closes the data paths
fileOut.close();// closes the data paths
}catch(IOException i)//exception stuff
{
i.printStackTrace();
}
to deserialze it use this:
try// If this doesnt work throw an exception
{
FileInputStream fileIn = new FileInputStream(name+".ser");// Read serial file.
ObjectInputStream in = new ObjectInputStream(fileIn);// input the read file.
object = (Object) in.readObject();// allocate it to the object file already instanciated.
in.close();//closes the input stream.
fileIn.close();//closes the file data stream.
}catch(IOException i)//exception stuff
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)//more exception stuff
{
System.out.println("Error");
c.printStackTrace();
return;
}
To serialize an object, create an ObjectOutputStream and call writeObject.
// Write to disk with FileOutputStream
FileOutputStream f_out = new
FileOutputStream("myobject.data");
// Write object with ObjectOutputStream
ObjectOutputStream obj_out = new
ObjectOutputStream (f_out);
// Write object out to disk
obj_out.writeObject ( myArray );
Reference
You can serialize many kinds of objects. Yes, an array is a object too (#see Array class). If you don't wan't the limitations of Arrays, you could use one of the Container classes (eg LinkedList) too. The serialization works the same way.
Write a class that manages this array. Put this class, along with classes it depends on, in its own JAR. Re-use JAR across multiple programs.
If you use Eclipse, you can do that by creating a new Java project (let's call it project OM - from Object Model) and putting the Foo and FooManager classes there. Then in each project you want to reuse the objects, in the Build Properties of the project add the OM project to the class path and to the exports tab. That's it.

Serializing a java object

I'm trying to serialize java objects but i keep getting a list of errors. my program accepts multiple values and creates an instance of a class with them. the created object then gets stored in a StorageSystem class... it looks something like this
aCD = new CD(title, artist, playTime, numOfTracks);
store.addItem(aCD);
Then in the storage system i add the stored object to an arrayList... what i also want to do is add the object to a serialized file... my method for doing this is below... Am i going about this the wrong way. thanks...
public void addItem(Item hold) // adds object to the ArrayList
{
itemList.add(hold);
totalStored++;
FileOutputStream f_out;
try
{
FileOutputStream fout = new FileOutputStream("thequeue.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(hold);
oos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
Code appears 'ok' . Theses are my observations :
Your class must implement the Serializable interface
FileOutputStream f_out; is never read
Instead of appending single object why don’t you put the entire ArrayList i.e (itemList) to the
object output stream
Catch 'IOException' first before trying 'Exception'
Code seems ok, except a double, unclear decaration (first f_out then fout declared and used).
Are you sure that classes that you want to serialize do implement the Serializable tag interface? In anycase I suggest you to write the whole ArrayList to the object output stream instead that trying to append single objects.
Well, it's not going to do what you want because every time you open the FileOutputStream it's going to overwrite the last file -- so you'll always have exactly one item in the file.
Also, your FileOutputStream is named f_out when you declare it outside the scope of the try, but you then create another one named fout inside that scope.
I'm not exactly sure what happens if you close the ObjectOutputStream instead of the FileOutputStream -- I think it should close the FileOutputStream but I'm not sure.

Categories