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 implementsSerializable
.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 haveHashSet
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")
)).