public void writeObject(String outFile) {
try {
FileOutputStream fos = new FileOutputStream(outFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Student[] copy = this.getStudents();
for (Student st : copy){
oos.writeObject(st);}
oos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
The code above is the function I use to serialize the contents of my repository,getStudens() is returning an array of my data.
public void readSerialized(String fileName) throws Exception {
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
while(fis.available()>0){
ctrl.addC((Student) ois.readObject());}
ois.close();
}
This my deserialization function which should recreate my data and add it again in my repository.The problem is that it doesn't recreate the data I had in my repository when I serialized it first.
What I had in repository before serialization:
1 a 4.0 6.0
2 b 10.0 10.0
3 c 2.0 2.0
4 d 8.0 2.0
5 e 6.0 2.0
What the deserialization returns:
0 3.0
0 5.0
Does this means that my serialization function isn't correct or something goes wrong when I deserialize?
Your code is needlessly complicated and using available() is always rather confusing I find. It means you can read without a system call it doesn't mean there is nothing left.
I suggest just serializing the array.
FileOutputStream fos = new FileOutputStream(outFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(this.getStudents());
oos.close();
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
Student[] copy = (Student[]) ois.readObject();
ois.close();
In Java, arrays are objects too.
Related
In my file I have saved my hashmap in the header which I can succesfully read, but when I try to read the following bytes, I get an error:
java.io.StreamCorruptedException: invalid type code: C9
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(Unknown Source)
Here's my code:
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
try {
map = (HashMap<Integer, String>) ois.readObject();
byte b = ois.readByte();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
How I write:
FileOutputStream os = new FileOutputStream(fileOutPath);
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(codePathMap);
BitSet buffer = new BitSet();
for (int i = 0; i < file.length; i++) {
for (int y = 0; y < codePathMap.get(i).length(); i++) {
if (codePathMap.get(b).charAt(i) == '1') {
buffer.set(bitIndex);
}
}
}
os.write(buffer.toByteArray());
There's a mismatch between writes and reads algorithms.
Short story, you're using FileOutputStream in order to write your byte[], but ObjectInputStream in order to read it. Those classes uses different ways of how they treat the stored data.
Hence, you SHOULD always use ObjectOutputStream/ObjectInputStream.
So, just to fix your error, instead of using FileOutputStream:
os.write(buffer.toByteArray());
you might use ObjectOutputStream (oos) in order to write the byte[] as:
oos.write(buffer.toByteArray());
Side note: invalid type code: C9, C9 is actual value of the written byte[], so C9 is 201, which ObjectInputStream interprets as Java type (that's how ObjectOutputStream serializes the data.
I'm trying to update files .ser :
Here's a snippet, without all useless stuffs (try ...etc)
String file1 = "data.ser";
InputStream fis = this.getClass().getResourceAsStream(file1);
InputStream buffer = new BufferedInputStream(fis);
ObjectInputStream ois = new ObjectInputStream(buffer)
ArrayList<Object[]> list = new ArrayList<>();
list = (ArrayList) ois.readObject();
//Reading works fine, I got all my data in list
/*
Some operations in list
*/
OutputStream fout;
fout = new FileOutputStream(file1);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file1));
//Here I tried to verify list; it's okay, all is there
oos.writeObject(list);
//I tried also some print just after that, and it works
This doesn't update my file; what can be the trouble?
PS: on IDE, all is fine, but when running jar, it's not; is that possible that I can't change files in jar ?!
I am trying to test a program and for that I need to access ReadExternal function but I am getting StreamCorrupted exception on ObjectInputStream.
I know I need to use the object written by WriteObject but dont know how to do it...
ObjectOutputStream out=new ObjectOutputStream(new ByteArrayOutputStream());
out.writeObject(ss3);
ss3.writeExternal(out);
try{
ByteInputStream bi=new ByteInputStream();
bi.setBuf(bb);
out.write(bb);
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bb));
String s1=(String) in.readObject();
}
catch(Exception e){
e.printStackTrace();
}
Apparently, you are trying to write the same object twice to the output stream:
out.writeObject(ss3);
ss3.writeExternal(out); // <-- Remove this!
The second write makes wrong use of the writeExternal() method, which should never be called explicitly but will be called by the ObjectOutputStream.
And: out.write(bb); tries to write the content of bb to the ObjectOutputStream. That's probably not what you want.
Try it like this:
// Create a buffer for the data generated:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out=new ObjectOutputStream( bos );
out.writeObject(ss3);
// This makes sure the stream is written completely ('flushed'):
out.close();
// Retrieve the raw data written through the ObjectOutputStream:
byte[] data = bos.toByteArray();
// Wrap the raw data in an ObjectInputStream to read from:
ByteArrayInputStream bis = new ByteArrayInputStream( data );
ObjectInputStream in = new ObjectInputStream( bis );
// Read object(s) re-created from the raw data:
SomeClass obj = (SomeClass) in.readObject();
assert obj.equals( ss3 ); // optional ;-)
ss3.writeExternal(out);
You shouldn't be calling that method directly. You should be calling
out.writeObject(ss3);
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 2345);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
Map<Integer, Integer> testMap = new HashMap<Integer, Integer>();
testMap.put(1,1);
oos.writeObject(testMap);
oos.flush();
testMap.put(2,2);
oos.writeObject(testMap);
oos.flush();
oos.close();
}
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(2345);
Socket s = ss.accept();
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
System.out.println((HashMap<Integer, Integer>) ois.readObject());
System.out.println((HashMap<Integer, Integer>) ois.readObject());
ois.close;
}
The code above is from two files.
When running them, the console prints the same result:
{1=1}
{1=1}
How can this happen?
An ObjectOutputStream remembers the objects it has written already and on repeated writes will only output a pointer (and not the contents again). This preserves object identity and is necessary for cyclic graphs.
So what your stream contains is basically:
HashMap A with contents {1:1}
pointer: "HashMap A again"
You need to use a fresh HashMap instance in your case.
As Thilo already said, an ObjectOutputStream keeps a cache of things it has written already. You can either use a fresh map as he suggests, or clear the cache.
Calling ObjectOutputStream.reset between the calls to writeObject will clear the cache and give you the behavior you originally expected.
public static void main(String[] args) throws IOException,
ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
HashMap<Integer, Integer> foo = new HashMap<>();
foo.put(1, 1);
oos.writeObject(foo);
// oos.reset();
foo.put(2, 2);
oos.writeObject(foo);
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
System.out.println(ois.readObject());
System.out.println(ois.readObject());
}
}
I have an array list that I want to serialize please advise how to I will be able to do that..
ArrayList list=new ArrayList();
list.add("Ram");
list.add("Sachin");
list.add("Dinesh");
list.add(1,"Ravi");
list.add("Dinesh");
list.add("Anupam");
System.out.println("There are "+list.size()+" elements in the list.");
System.out.println("Content of list are : ");
Iterator itr=list.iterator();
while(itr.hasNext())
System.out.println(itr.next());
}
}
I want to use the serialization mechanism so that I can save it in file
It is very simple. Both ArrayList and String (that you store in the list) implement Serializable interface, so you can use the standard java mechanism for serialization:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myfile"));
oos.writeObject(list);
............
oos.fluch();
oos.close();
In this example I wrapped FileOutputStream with ObjectOutputStream but obviously you can use any other payload stream.
You have to create your own methods for serializing and deserializing objects. The below are useful methods for doing just that.
public static Object deserializeBytes(byte[] bytes) throws IOException, ClassNotFoundException
{
ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bytesIn);
Object obj = ois.readObject();
ois.close();
return obj;
}
public static byte[] serializeObject(Object obj) throws IOException
{
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bytesOut);
oos.writeObject(obj);
oos.flush();
byte[] bytes = bytesOut.toByteArray();
bytesOut.close();
oos.close();
return bytes;
}