【问题标题】:Can't read multiple objects from a file无法从文件中读取多个对象
【发布时间】:2013-04-11 14:20:57
【问题描述】:

我正在尝试将 (Lieu) 对象放入 ArrayList 但在代码末尾,我的列表仍然是空的。我一直在网上寻找答案,但我发现的只是“将您的对象写入集合然后阅读集合”。但是文件已经写好了,我需要找到一种方法将所有(Lieu)对象放在一个 ArrayList 中。

这是编写代码(我无法修改):

public static void main(String[] args) {
        Lieu<Double, String> p1;
        Lieu<Double, String> p2;
        Lieu<Double, String> p3;
        SegmentGeo<String> e1;
        SegmentGeo<String> e2;
        SegmentGeo<String> e3;
        Parcelle<String> p = new Parcelle<String>();
        ArrayList<Mesure<Point<Double>, String>> segs;
        p1 = new Lieu<Double, String>(45.573715, -73.900295, "p1");
        p2 = new Lieu<Double, String>(45.573882, -73.899748, "p2");
        p3 = new Lieu<Double, String>(45.574438, -73.900099, "p3");
        e1 = new SegmentGeo<String>(p1, p2, "Parcelle test");
        e2 = new SegmentGeo<String>(p2, p3, "Parcelle test");
        e3 = new SegmentGeo<String>(p3, p1, "Parcelle test");
        segs = new ArrayList<Mesure<Point<Double>, String>>();
        segs.add(e1);
        segs.add(e2);
        segs.add(e3);
        try {
            p.setMesures(segs);
        } catch (TrajectoireNonValideException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        ObjectOutputStream ois = null;
        try {
            ois = new ObjectOutputStream(new FileOutputStream("essai.txt"));
            ois.writeObject(p.informationCumulee());
            ois.writeObject(p1);
            ois.writeObject(p2);
            ois.writeObject(p3);
        } catch (EOFException ex) {
            System.out.println("Fin de fichier atteinte.");
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

这就是我想要做的:

public void actionPerformed(ActionEvent arg0) {
    JFileChooser chooser = new JFileChooser();
    int retour = chooser.showOpenDialog(getParent());
    if(retour==JFileChooser.APPROVE_OPTION){
          try{
       FileInputStream fis = new FileInputStream(chooser.getSelectedFile().getName());
       ObjectInputStream ois = new ObjectInputStream(fis);
       champNom.setText((String) ois.readObject());//that's just to display the name
       while (ois.available()!=0) 
       { 
            temp = (Lieu)ois.readObject();
            l.add(temp);
       }
       ois.close();
       System.out.print(l.size());//The size is 0
       }
       catch (FileNotFoundException e) {
           e.printStackTrace();
       }
       catch (IOException e) {
           e.printStackTrace();
       } 
       catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
     }

【问题讨论】:

    标签: java file object objectinputstream


    【解决方案1】:

    正如 Joetjah 所说,available() 不像听起来那样有效。

    一个不是超级优雅但效果惊人的解决方案是捕获Exceptions,当没有任何内容可读取或其他异常时将抛出,例如:

        try {
            while (true)
                l.add((Lieu<Double,String>)ois.readObject());
        } catch (ClassNotFoundException | IOException e) {
            //Expecting a EOFException here
        } finally {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    每当读取时抛出异常(并且在某些时候会有一个!),它将停止读取。

    【讨论】:

      【解决方案2】:

      Available doesn't do what you think it does

      available() 不会返回要读取的数据量,而是可以在没有阻塞的情况下读取的数据量(暂停以等待来自文件/套接字/数据库/等的更多数据)。在某些情况下,这可能会在仍有应读取的字节时返回零 - 0 表示现在有 0 个字节可用(没有阻塞)。这可能由于各种原因而发生 - 硬盘驱动器可能正忙于重新定位其磁性阅读器,或者网络连接可能正忙,或者您可能正在某个地方等待用户输入某些内容,然后才能发送他们的信息。或者可能是因为您正在阅读的文件确实没有额外的字节要读取,因为您已经到了结尾。使用 available() 你无法知道是否应该尝试读取字节。

      使用流复制文件的更正确方法是检查 read 的返回值是否为文件结束值 (-1):

      InputStream is = // some input
      OutputStream os = // some output
      byte buffer = new byte[1024];
      int bytesRead;
      while ((bytesRead = is.read(buffer)) != -1) {   
         os.write(buffer, 0, bytesRead);
      }
      

      当这段代码完成时,你就知道所有的字节真的已经被读取和复制了,因为 while 循环直到 read() 返回 -1 才完成,表示输入结束。

      现在,就你的情况而言,我建议将其转向其他方向,例如:

      FileInputStream fis = new FileInputStream(chooser.getSelectedFile().getName());
      ObjectInputStream ois = new ObjectInputStream(fis);
      Object obj = ois.readObject();
      while (obj != null) 
      { 
          champNom.setText((String)obj); 
      
          if (obj instanceof Lieu<Double, String>) 
              l.add(obj);
      
          obj = ois.readObject();
      }
      ois.close();
      System.out.print(l.size());
      

      【讨论】:

      • 这是有问题的。首先,由于某些原因,您在这种情况下的建议无法编译,而且 IMO 也有问题。除了检查空对象之外,空检查没有做任何事情。如果在 OPs 文件中碰巧有一个为 null 的 Lieu,它将无法读取文件的其余部分。这将在最后抛出 EOFException。
      猜你喜欢
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 1970-01-01
      • 2020-08-11
      • 2021-11-20
      • 1970-01-01
      • 2016-08-15
      相关资源
      最近更新 更多