Issue
So far I have found that there is a way to do appending in serialization by making a sub-class but that seems like a lengthy way. Is there any better way to do appending in serialization?
I have this vectorlist in a class named Course
private Vector<Student> StudentList = new Vector<>();
I have 2 objects of course. 3 students are enrolled in 1 course and 2 students are enrolled in another. Now I call this method which is doing serialization in the file but when I call it with my 2nd course object, it replaces previous content.
public void Serialization() {
try {
File file = new File("EnrolledStudentsSerial.txt");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fo = new FileOutputStream(file);
ObjectOutputStream output = new ObjectOutputStream(fo);
output.writeObject("Course: " + this.name + "\n\nEnrolled Students: ");
for (int i = 0; i < StudentList.size(); i++) {
Student p_obj = StudentList.elementAt(i);
String content = "\n\tStudent Name: " + p_obj.getName() + "\n\tStudent Department: " + p_obj.getDepartment() + "\n\tStudent Age: " + p_obj.getAge() + "\n";
output.writeObject(content);
}
output.writeObject("\n");
fo.close();
} catch (IOException ioe){
System.out.println("Error: " + ioe.getMessage());
}
}
Solution
If you want to append to a file, instead of replacing the content, you need to tell the FileOutputStream
that, by adding an extra argument and call FileOutputStream(File file, boolean append)
. FYI: don't do that with an ObjectOutputStream
.
You don't need to call createNewFile()
, since FileOutputStream
will do that, whether appending or not.
However, you are not actually serializing your objects, since you're serializing strings instead. What you're doing makes no sense. Since you seem to want the result to be a text file (you're writing text, and file is names .txt
), you should forget about ObjectOutputStream
, and use a FileWriter
instead.
Better yet, instead of using the old File I/O API, you should be using the "newer" NIO.2 API that was added in Java 7. You should also be using try-with-resources. Same goes for the ancient Vector
class, which was replaced by ArrayList
in Java 1.2.
Java naming convention is for field and method names to start with lowercase letter. And since your method is not "serializing" anymore, you should give it a better name.
Applying all that, your code should be:
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
private ArrayList<Student> studentList = new ArrayList<>();
public void writeToFile() {
Path file = Paths.get("EnrolledStudentsSerial.txt");
try (BufferedWriter output = Files.newBufferedWriter(file, CREATE, APPEND, WRITE)) {
output.write("Course: " + this.name + "\n\nEnrolled Students: ");
for (Student student : studentList) {
String content = "\n\tStudent Name: " + student.getName() +
"\n\tStudent Department: " + student.getDepartment() +
"\n\tStudent Age: " + student.getAge() + "\n";
output.write(content);
}
output.write("\n");
} catch (IOException ioe){
System.out.println("Error: " + ioe.getMessage());
}
}
Answered By - Andreas
Answer Checked By - Candace Johnson (JavaFixing Volunteer)