package com.codegym.task.task20.task2022;
import java.io.*;
import java.util.Objects;
/*
Overriding serialization in a thread
*/
public class Solution implements Serializable, AutoCloseable {
//Write the verification code yourself in the main method:
//1) create an instance of the Solution class
//2) write data to it (writeObject)
//3) serialize the Solution class (writeObject(ObjectOutputStream out))
//4) deserialize, get a new object
//5) write data to the new object (writeObject)
//6) verify that the file contains the data from Items 2 and 5
public static void main(String[] args) throws Exception {
//FIXME: how to prevent StreamCorruptedException? => first create out then in
String fileName = "/Users/lilianetop/Desktop/task2022.txt";
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
Solution solution = new Solution(fileName);
//solution.writeObject("What will happen?");
System.out.println(solution.toString());//how to get the text back?
out.writeObject(solution);
out.flush();//why do this? is it necessary?
Solution solution1 = (Solution) in.readObject();
//solution1.writeObject("This text is NOT disappearing");
System.out.println((solution1.toString()));//it shows the memory location of the object but doesn't show the string
solution.close();
System.out.println(solution.equals(solution1));//returns false even if I remove the first and second string why?
}
//1. The stream field must be declared with the transient modifier.
transient private FileOutputStream stream;
private String fileName;
public Solution() {
}
//5. In the Solution class constructor, the stream field must be initialized with a new FileOutputStream object with the argument (fileName).
public Solution(String fileName) throws FileNotFoundException {
this.fileName = fileName;
this.stream = new FileOutputStream(fileName);
}
public void writeObject(String string) throws IOException {
stream.write(string.getBytes());
stream.write("\n".getBytes());
stream.flush();
}
//2. The writeObject(ObjectOutputStream out) method should not call the close method on the stream passed as an argument.
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
//out.close();
}
//3. The readObject(ObjectInputStream in) method should not call the close method on the stream passed as an argument.
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
//4. In the readObject(ObjectInputStream in) method, the stream field must be initialized
// with a new FileOutputStream object using the arguments (fileName, true).
in.defaultReadObject();
stream = new FileOutputStream(fileName, true);
//in.close();
}
@Override
public void close() throws Exception {
System.out.println("Closing everything!");
stream.close();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Solution)) return false;
Solution solution = (Solution) o;
return stream.equals(solution.stream);
}
@Override
public int hashCode() {
return Objects.hash(stream);
}
}
Couple of questions for a better understanding.
Under discussion
Comments (4)
- Popular
- New
- Old
You must be signed in to leave a comment
Guadalupe Gagnon
18 January 2021, 16:25
1)"how to get the text back?"
The text is being written to a file, not to the object, you would have to read that file to get the text back. Also, the FileInputStream from the Solution class should be a separate file from the one being used by the input/output streams should be a different file. Otherwise the data being written by the ObjectOutputStream will override the data being written by Solution.stream.
2) "out.flush();//why do this? is it necessary?"
Remember the task you were testing writing to a file and then reading, when it wasn't reading anything? The flush() method ends the current writing and will save that data in the file. It functions like the close() method excepting that it leaves the Stream open. Try this code with the flush() commented out, then uncomment it and try it:
+2
Guadalupe Gagnon
18 January 2021, 16:51useful
#3 System.out.println(solution.equals(solution1));//returns false even if I remove the first and second string why?
This is because you are comparing streams in the equals method. The only way streams are equal if they are the same object. Take this code for example:
Try comparing Solution.fileName instead of Solution.stream. +1
Liliane Top Backend Developer at Procura
18 January 2021, 17:02
1) clear!! the confusion was indeed writing text to a file as opposed an object.
2) I didn't know that flush keeps the stream open but ensures that everything is written to the file: First it was not there an dafter uncommenting fw.flush() VOILA!
3) Yes i figured it out. I overrride the equals() and hasCode() and now compare the field fileName. CLEAR!!
4) What is still a bit confusing is why we are initialising the outputStream in the readObject() method. If I just put it in the writeObject(String String) it seems that the code works the same. What am I missing?

0
Liliane Top Backend Developer at Procura
18 January 2021, 17:04
What is also unclear why this works :
But this doesn't:
0