首页 > 解决方案 > 如何从 ObjectInputStream 中读取所有对象

问题描述

我有一个包含一些信息的文件,如何阅读所有信息?

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

标签: javafile

解决方案


你有几个解决方案,都取决于输入:

  • 您可以迭代直到流被完全消耗:我认为这是我为您提供的解决方案中最糟糕的解决方案。更糟糕的是,您正在检查是否达到 EOF,而您应该知道何时完成(例如:您的文件格式错误)。

    Set<Name> result = new HashSet<>();
    try { 
      for (;;) { 
        result.add((Name)objectInputStream.readObject());
      }
    } catch (EOFException e) {
      // End of stream
    } 
    return result;
    
  • 产生输入时,序列化一个集合并调用readObject()它。Serialization应该能够读取集合,只要每个对象实现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();
      }
    }
    
  • 生成输入时,您可以添加一个int指示要读取的对象数量并对其进行迭代:这在您并不真正关心集合的情况下很有用(HashSet)。生成的文件会更小(因为您没有HashSet元数据)。

    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();
    }
    

同样,它们也很好,但是由于它们使用/Set删除重复项,因此如果您对/的定义在事后发生更改,您可能会得到更少的对象(例如:您是区分大小写的,而现在不是,例如:)。hashCode()equals()equalshashCodeNamenew Name("AA").equals(new Name("aa"))


推荐阅读