0

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

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
VeraTuran
  • 23
  • 3
  • Please tell the details of your problem -- what exception are you seeing (if any)? Also, an OOS cannot write to a text file since it outputs binary data, not text data. – Hovercraft Full Of Eels Apr 14 '22 at 13:06
  • java.io.EOFException at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2956) at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3451) at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:988) at java.base/java.io.ObjectInputStream.(ObjectInputStream.java:419) at idpack.Main.main(Main.java:30) – VeraTuran Apr 14 '22 at 13:54
  • You appear to be trying to open the file for both writing and reading at the same time. That won't work. Also ObjectInputStream will throw an EOFException when it has completed reading in the data as per the API. – Hovercraft Full Of Eels Apr 14 '22 at 13:59
  • Whats puzzling is, when I write ```oos.writeObject(new User ("someStringid", "someotherstring")); ``` directly in the code it absolutely will write it in the text file. If oos can't get String data, then how is this possible? And how do I get it to write scanner input? – VeraTuran Apr 14 '22 at 13:59
  • I see! What I am trying to do is basically to get a scanner going in the console, that writes on the text file, then after having finished writing, display the content in the console as well. How would I go about that then? – VeraTuran Apr 14 '22 at 14:02
  • Do you need a User object in the file or its properties like id from scanner? if only id so write id and not through ObjectOutputstream – Vadim Apr 14 '22 at 14:03
  • *"If oos can't get String data"* -- I never stated this. I stated that OOS doesn't write data as text. It writes data as binary data. – Hovercraft Full Of Eels Apr 14 '22 at 14:04
  • oos must not write as text - it writes object serialized to bytes in Java internal format. BTW String is also an Object - everything in Java are objects, but few primitives – Vadim Apr 14 '22 at 14:05

1 Answers1

0

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...
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
Vadim
  • 4,027
  • 2
  • 10
  • 26