2013-04-11 51 views
2

我試圖將(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(); 
     } 
    } 

回答

1

由於Joetjah說,available()不起作用像它聽起來像。

一個解決方案,是不是超優雅,但工作出奇地好是剛剛趕上Exception■當沒有什麼留下來讀取或其他異常將被拋出,因爲這樣的:

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

每當有一個閱讀時會拋出異常(並且在某些時候會有一個!),它會停止閱讀。

+0

是這個作品!非常感謝 – 2013-04-11 15:33:17

0

Available doesn't do what you think it does

可用()不不返回剩餘要讀取的數據量,而是可以無阻塞地讀取數據量(暫停等待來自文件/套接字/數據庫等的更多數據)。在某些情況下,這可能會返回零,而仍然有字節應該被讀取 - 0表示現在有0個字節可用(沒有阻塞)。這可能會因爲各種原因而發生 - 硬盤驅動器可能正在忙於重新定位其磁性閱讀器,或者網絡連接可能很忙,或者您可能正在等待用戶輸入某些內容,然後才能發送信息。或者這可能是因爲你正在閱讀的文件實際上沒有額外的字節可讀,因爲你已經達到了最後。使用available()你無法知道你是否應該嘗試讀取字節。

使用流複製文件一個更正確的方法是檢查讀取的返回值結束文件中的值(-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); 
} 

當代碼完成後,您知道所有的字節確實已被讀取和複製,因爲直到read()返回-1,while循環纔會完成,表明輸入結束。現在

,你的情況,我建議,它採取一些其他的方向,就像這樣:

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()); 
+0

這是有問題的。首先,在這種情況下,您的建議由於幾個原因不可編譯,但也是錯誤的IMO。空檢查除了檢查空對象之外沒有做任何事情。如果在OPs文件中碰巧有一個null,它將無法讀取文件的其餘部分。這將在最後拋出EOFException。 – ddmps 2013-04-11 14:51:54