Why doesn't the ObjectOutputStream write the variables in the file as intended?

334 Views Asked by At

I am learning Java and I'm trying to get a programme to write the attributes of one class instance of another into a .txt file, like a phonebook for instance. I have a class User :

package idpack;

import java.io.Serializable;

public class User implements Serializable {
    private String id;
    private String mdp;
    
    public User (String id, String mdp) {
        this.id = id;
        this.mdp = mdp;
    }
}

and a main, in which I declare my ObjectOutputStream, ObjectInputStream, my scanner and then try to write the input from the scanner into the file. It looks like this:

package idpack;

// import everything here

public class Main {

    public static void main(String[] args) throws IOException {
        ObjectInputStream ois;
        ObjectOutputStream oos;
        
        try {
            oos = new ObjectOutputStream(
                    new BufferedOutputStream(
                            new FileOutputStream(
                                    new File("identifiant.txt"))));
            
            ois = new ObjectInputStream(
                    new BufferedInputStream(
                            new FileInputStream(
                                    new File ("identifiant.txt"))));
            
            ArrayList<User> ul = new ArrayList<User>();
            Scanner scan = new Scanner(System.in);
            boolean isTyping = true;
            
            try {
                while(isTyping) {
                    System.out.println("press['x' to exit]\n = type in the id :");
                    String id = scan.next();
                    if (id.equalsIgnoreCase("x")) {
                        break;
                    }
                    System.out.println("type in the number :");
                    String mdp = scan.next();
                    User u = new User(id, mdp);
                    ul.add(u);
                    oos.writeObject(new User (id, mdp));
                }
                
                for (User t:ul) {
                    System.out.println(((User)ois.readObject()).toString());
                }
                
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            
            oos.close();
            ois.close();
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (EOFException e) { // the console throws EOFException ObjectInputStream of all kinds, so I though catching them would be a good idea, but this code doesn't do anything to remedy it
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I have tried moving around where I close oos and ois and getting rid of the first try catch block, but to no avail. The scanner in itself is working, I largely used this post as a model: Adding objects to an array list with scanner in Java

1

There are 1 best solutions below

0
On

Looks like - there are some basic Java conceptions you missed:

  1. "Object" in Java is what you defined and it is internal for java object not represented by String or anything else.

  2. When you use ObjectOutputStream to write object - JVM serialize it into internal for Java serilized form of bytes. To use it your User object must implements java.io.Serializable interface.

you need to check - does User class definition looks like

public class User implements Serializable {
...
  1. then when you write your User object what will be in file is those bytes which can be read back as User object by

    ois.readObject()
    

So... your file regardless of how you name it will have bytes which are serializable form of your Object.

More:

  • when you try to print your object using toString() method it prints return from User.toString() method - if it overrides Java default one for Object class. If User class does not override toString() it will look like

    User@1234ab56

  • you do not need to wrap FileOutputSteram to BufferedOutputStream (same for FielInputStream) Object streams will work without it.

  • and keep in mind your code creates two different User objects at

      User u = new User(id, mdp); // u is the one
    
      oos.writeObject(new User (id, mdp)); // another one written to the file 
    

did you do it on purpose?

  • this loop has no sense at all

    for (User t:ul) {
        System.out.println(((User)ois.readObject()).toString());
    }
    

if there are 2 or more user objects in ul - at second attempt to read there will be EOF exception - ois is already at the end of file.

UPD: I feel like "Object" conception from script languages (e.g. JavaScript) misleads you... what I can suggest:

  1. comment out all reading operations and run only "write" part.
  2. examine result file - is it what you expected? if not make it "write" part to do what you want to read.
  3. The work on "read" part.
  4. BTW you have to properly close OutputStream/file before attempt to read from it
  5. when you read from it once you need to close it and have a new InputStream to start over...