Java – How to read all objects from ObjectInputStream

How to read all objects from ObjectInputStream… here is a solution to the problem.

How to read all objects from ObjectInputStream

I have a file with some information, how can I read all the information?

Name names;    
try (FileInputStream fileInputStream = new FileInputStream(file)) {
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            names = (Name) objectInputStream.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

Solution

You have several solutions, all depending on the input:

  • You can iterate until the stream is fully consumed: I think this is the worst solution of the solutions I offer you. Worse, you’re checking to see if the EOF has been reached, and you should know when it’s done (example: you’re in the wrong file format).

    Set<Name> result = new HashSet<>();
    try { 
      for (; ;) { 
        result.add((Name)objectInputStream.readObject());
      }
    } catch (EOFException e) {
       End of stream
    } 
    return result;
    
  • When generating input, serialize a collection and call readObject() on it. Serialization should be able to read collections, as long as each object implements Serializable.

    static void write(Path path, Set<Name> names) throws IOException {
      try (OutputStream os = Files.newOutputStream(path);
           ObjectOutputStream oos = new ObjectOutputStream(os)) {
        oos.writeObject(names);    
      }       
    } 
    
    static Set<Name> read(Path path) throws IOException {
      try (InputStream is = Files.newInputStream(path);
           ObjectInputStream ois = new ObjectInputStream(is)) {
         WARN Files.newInputStream is not buffered; ObjectInputStream might
         be buffered (I don't remember).
        return (Set<Name>) ois.readObject();
      }
    }
    
  • When generating input, you can add an int to indicate the number of objects to read, and iterate over them: this is useful in situations where you don’t really care about the object collection (HashSet). The resulting file will be smaller (because you don’t have HashSet metadata).

    int result = objectInputStream.readInt();
    Name[] names = new Name[result];  do some check on result!
    for (int i = 0; i < result; ++i) {
      names[i] = (Name) objectInputStream.readObject();
    }
    

Also, Sets are fine, but since they remove duplicates using hashCode()/equals(), if your equals/hashCode definition changes after the fact (e.g.: your Name is case-sensitive , now case-insensitive, for example: new name ("AA").equals(new name ("aa"))).

Related Problems and Solutions