I have a problem with reading objects from file Java.
file is anarraylist<projet>
This is the code of saving objects :
try {
FileOutputStream fileOut = new FileOutputStream("les projets.txt", true);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
for (projet a : file) {
out.writeObject(a);
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
And this is the code of reading objects from file ::
try {
FileInputStream fileIn = new FileInputStream("les projets.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
while (in.available() > 0){
projet c = (projet) in.readObject();
b.add(c);
}
choisir = new JList(b.toArray());
in.close();
} catch (Exception e) {
e.printStackTrace();
}
Writing is working properly. The problem is the reading... it does not read any object (projet) What could be the problem?
As mentioned by EJP in comment and this SO post . if you are planning to write multiple objects in a single file you should write custom ObjectOutputStream , because the while writing second or nth object header information the file will get corrupt.
As suggested by EJP write as ArrayList , since ArrayList is already Serializable you should not have issue. as
out.writeObject(file) and read it back as ArrayList b = (ArrayList) in.readObject();
for some reason if you cant write it as ArrayList. create custome ObjectOutStream as
class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream(OutputStream os) throws IOException {
super(os);
}
#Override
protected void writeStreamHeader() {}
}
and change your writeObject as
try {
FileOutputStream fileOut= new FileOutputStream("les_projets.txt",true);
MyObjectOutputStream out = new MyObjectOutputStream(fileOut );
for (projet a : file) {
out.writeObject(a);
}
out.close();
}
catch(Exception e)
{e.printStackTrace();
}
and change your readObject as
ObjectInputStream in = null;
try {
FileInputStream fileIn = new FileInputStream("C:\\temp\\les_projets1.txt");
in = new ObjectInputStream(fileIn );
while(true) {
try{
projet c = (projet) in.readObject();
b.add(c);
}catch(EOFException ex){
// end of file case
break;
}
}
}catch (Exception ex){
ex.printStackTrace();
}finally{
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Related
I'm working on appending objects to a binary file. My file is:
File f=new File("person.dat");
I'm getting an error (java.io.StreamCorruptedException: invalid stream header: 79737200) when I attempt to open the binary file. As far as I can tell the program writes the data just fine, but as soon as I try reading from it, I get the above error. Any help is appreciated!
My Code to write:
AppendObjectOutputStream out = null;
try {
out = new AppendObjectOutputStream(new FileOutputStream(f, true));
out.writeObject(new Student(name, age));
out.flush();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
out.close();
}
My class for making appendable:
public class AppendObjectOutputStream extends ObjectOutputStream {
public AppendObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {
reset();
}
}
My partial code for reading and adding objects to an ArrayList:
Course course = new Course();
Student st = null;
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new FileInputStream("person.dat"));
try
{
while (true)
{
st = (Student) in.readObject();
course.addAccount(st); //adds student object to an ArrayList in
//class Course
}
}
catch (EOFException ex) {
}
}
catch (Exception ex) {
ex.printStackTrace();
} finally {
in.close();
}
UPDATE:
Current code to read but its not printing anything to screen:
try(ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(Files.newInputStream(f))))
{
while (ois.available() > 0)
{
st = (Student) ois.readObject();
studentlist.addAccount(st);
System.out.println(st.getStudentNumber());
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
This is how I write to file:
Path f = Paths.get("person.dat");
try (ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(Files.newOutputStream(f, StandardOpenOption.APPEND))))
{
oos.writeObject(new Student(name,age));
}
catch(Exception ex)
{
ex.printStackTrace();
}
Rather than trying to fix your utility classes, I suggest to use the standard classes of the NIO.2 File API.
Try something like (untested):
Path personDataFilePath = Paths.get("person.dat");
// or Java 11:
// Path personDataFilePath = Path.of("person.dat");
try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(Files.newOutputStream(personDataFilePath, StandardOpenOption.APPEND)))){
oos.writeObject(new Student(name,age));
} catch (IOException ex) {
// do some error handling here
}
and to read the file, something like (untested):
List<Student> students = new ArrayList<>();
try (ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(Files.newInputStream(personDataFilePath)))){
while (ois.available() > 0){
students.add((Student) ois.readObject());
}
} catch (IOException ex) {
// do some error handling here
}
I have modified the code to work around making a file "appendable". I write a single arraylist object to the file (the arraylist holds a list of student objects). When I want to add a student, I read the object (arraylist) from the file, add my new student to the arraylist and write the arraylist back to the file. It is now working and my file does not have an append format.
I create a client similarity, where clients register an account (an object is created) which is stored in a file.
Objects are written to the file as required, I override the writeStreamHeader() method. But when I try to read them all, their file throws an exception.
Write the objects to the file here.
public static void saveAccaunt(LoginAndPass gamers) {
boolean b = true;
FileInputStream fis = null;
try{
fis = new FileInputStream("student.ser");
fis.close();
}
catch (FileNotFoundException e)
{
b = false;
} catch (IOException e) {
e.printStackTrace();
}
try {
FileOutputStream fileOutputStream = new FileOutputStream("student.ser",true);
ObjectOutputStream os = null;
if(b = true){
os = new AppendingObjectOutputStream(fileOutputStream);
System.out.println("Объект добавлен!");
}else {
os = new ObjectOutputStream(fileOutputStream);
System.out.println("Создан");
}
os.writeObject(gamers);
os.close();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream("student.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
test = new ArrayList<>();
while (true){
test.add(objectInputStream.readObject());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(test.get(0));
}
Here is the error log for the exception thrown:
java.io.StreamCorruptedException: invalid stream header: 79737200
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:866)
at java.io.ObjectInputStream.(ObjectInputStream.java:358)
at Registratsiya.AllGamers.main(AllGamers.java:48)
Exception in thread "main" java.lang.NullPointerException
at Registratsiya.AllGamers.main(AllGamers.java:61)
I know I'm not doing something correctly. I know the file needs to be Serializable to read a text file.
I've got implements Serializable on the main class. But my readText and my writeText aren't converting.
Nothing is coming in when I read and when I write out the file is not text.
public static ArrayList<String> readText() {
ArrayList<String> read = new ArrayList<String>();
Frame f = new Frame();
FileDialog foBox = new FileDialog(f, "Reading serialized file",
FileDialog.LOAD);
foBox.setVisible(true);
String foName = foBox.getFile();
String dirPath = foBox.getDirectory();
File inFile = new File(dirPath + foName);
BufferedReader in = null;
ObjectInputStream OIS = null;
try {
in = new BufferedReader(new FileReader(inFile));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
String line = null;
try {
line = in.readLine();
} catch (IOException e1) {
e1.printStackTrace();
while (line != null) {
try {
FileInputStream IS = new FileInputStream(inFile);
OIS = new ObjectInputStream(IS);
inFile = (File) OIS.readObject();
} catch (IOException io) {
io.printStackTrace();
System.out.println("An IO Exception occurred");
}
catch (ClassNotFoundException cnf) {
cnf.printStackTrace(); // great for debugging!
System.out.println("An IO Exception occurred");
} finally
{
try {
OIS.close();
} catch (Exception e) {
}
}
}
}
return read;
}
public static void writeText(ArrayList<String> file) {
ArrayList<String> write = new ArrayList<String>();
Frame f = new Frame();
FileDialog foBox = new FileDialog(f, "Saving customer file",
FileDialog.SAVE);
foBox.setVisible(true);
String foName = foBox.getFile();
String dirPath = foBox.getDirectory();
File outFile = new File(dirPath + foName);
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter(outFile)));
for (int i = 0; i < write.size(); i++) {
String w = write.get(i);
out.println(file.toString());
}
}
catch (IOException io) {
System.out.println("An IO Exception occurred");
io.printStackTrace();
} finally {
try {
out.close();
} catch (Exception e) {
}
}
}
Nothing is coming in
You're never calling read.add(line) and you're attempting to read the file within an infinite loop inside of the catch block, which is only entered if you are not able to read the file.
Just use one try block, meaning try to open and read the file at once, otherwise, there's no reason to continue trying to read the file if it's not able to be opened
List<String> read = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(inFile)) {
String line = null;
while ((line = in.readLine()) != null) {
read.add(line); // need this
}
} catch (Exception e) {
e.printStackTrace();
}
return read;
Now, whatever you're doing with this serialized object stuff, that's completely separate, and it isn't the file or your main class that needs set to Serializable, it's whatever object you would have used a writeObject method on. However, you're reading and writing String objects, which are already Serializable.
when I write out the file is not text
Not sure what you mean by not text, but if you followed the above code, you'll get exactly what was in the initial file... Anyway, you do not need a write list variable.
You must use the individual lines of ArrayList<String> file parameter instead, but not file.toString()
for (String line:file) {
out.println(line);
}
out.close(); // always close your files and writers
This question already has answers here:
Appending to an ObjectOutputStream
(6 answers)
Closed 5 years ago.
I have a program utilizing the memento design pattern and want to save the state of each object into a file using serialization and return the object back. The problem is that I get a "java.io.StreamCorruptedException: invalid type code: AC" exception due to corrupt headers. I looked at Appending to an ObjectOutputStream and tried to implement the class but still can't get the program to work properly. Multiple objects should be saved in a file and the user passes a string into a function which should match part of the object's string representation.
public class Caretaker implements Serializable {
public void addMemento(Memento m) {
try {
// write object to file
FileOutputStream fos = new FileOutputStream("ConeOutput1.txt", true);
BufferedOutputStream outputBuffer = new BufferedOutputStream(fos);
AppendableObjectOutputStream objectStream = new AppendableObjectOutputStream(outputBuffer);
objectStream.writeObject(m);
objectStream.reset();
objectStream.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public Memento getMemento(String temp) {
try {
Memento result = null;
FileInputStream fis = new FileInputStream("ConeOutput1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
result = (Memento) ois.readObject();
while (result != null) {
Matcher m = Pattern.compile(temp).matcher(result.toString());
if (m.find()) {
return result;
}
else {
result = (Memento) ois.readObject();
}
ois.close();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
You should only use the appending ObjectOutputStream if the file already exists with data in it. If the file is new it needs the object stream header.
I want write list of objects into file, and then reading it one by one, and deleting respectively.
Writing and reading functions are below. For one by one reading,first I read all, then pop first, and other write to file again. it very ineffective and takes long time. So, what should I do to get better perfomance? Or maybe, there are other variant to solve this problem
public void writeToDisk(String filePath,TreeMap<String, ArrayList<Integer>> obj){
File file = new File(filePath);
FileOutputStream fout = null;
try {
fout = new FileOutputStream(file);
ObjectOutputStream o = new ObjectOutputStream(fout);
o.writeObject(obj);
o.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public TreeMap<String, ArrayList<Integer>> readFromDisk(String filePath){
TreeMap<String,ArrayList<Integer>> invertIndexMap = null;
File file = new File(filePath);
FileInputStream f;
try {
f = new FileInputStream(file);
ObjectInputStream s = new ObjectInputStream(f);
invertIndexMap = (TreeMap<String, ArrayList<Integer>>) s.readObject();
s.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return invertIndexMap;
}