2011-03-07 34 views
6

以下代碼會生成EOFException。這是爲什麼?Java帶有讀取對象的神祕EOF異常

public static Info readInfoDataFromFile(Context context) { 
    Info InfoData = null; 
    FileInputStream fis = null; 
    ObjectInputStream ois = null; 
    Object object = null; 

    if (context.getFileStreamPath("InfoFile.dat").exists()) { 
     try { 
      fis = context.openFileInput("InfoFile.dat"); 
      ois = new ObjectInputStream(fis); 
      Object temp; 
      try { 
       // here it throws EOF exception in while loop 
       while ((temp = ois.readObject()) != null) { 
        object = temp; 
       } 
      } catch (NullPointerException npe) { 
       npe.printStackTrace(); 
      } catch (EOFException eof) { 
       eof.printStackTrace(); 
      } catch (FileNotFoundException fnfe) { 
       fnfe.printStackTrace(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (ois != null) { 
        ois.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      try { 
       if (fis != null) { 
        fis.close(); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

堆棧跟蹤:

03-07 14:29:01.996: WARN/System.err(13984): java.io.EOFException 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.DataInputStream.readByte(DataInputStream.java:131) 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.nextTC(ObjectInputStream.java:628) 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:907) 
03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2262)03-07 14:29:01.996: WARN/System.err(13984):  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2217) 
03-07 14:29:01.996: WARN/System.err(13984):  at 
+2

的Javadoc:'任何試圖讀取對象數據超過由相應writeObject方法寫入的自定義數據的邊界將導致OptionalDataException與TRUE' – malinois

+0

的EOF字段值被拋出是的,我已經閱讀它但如何避免它? –

回答

9

取決於你的文件多少個對象包含。如果它只有一個對象,則可以一步反序列化。

try { 
    Object temp = ois.readObject(); 
} 
catch(Exception e) { 
    //handle it 
} 
+2

是的,但它會拋出錯誤EOF ..爲什麼? –

+0

請看堆棧跟蹤。 –

+6

@Aizaz:你爲什麼期望'readObject()'在文件末尾返回'null'?它沒有,它被指定始終返回對象或拋出異常。所以除非你明確地序列化了'null',否則你不應該期望'readObject()'返回'null'。 –

2

readObject()ObjectInputStream定義並不確定它將返回null到達流的末尾時。相反,如果您嘗試讀取超出文件末尾的其他對象,則會引發異常。

+0

那麼如何檢測我們在文件結尾?我的意思是如何避免EOF異常? –

+0

可以在文件中存儲信息,告訴您需要多少個對象,或者正確處理EOF異常。請記住,異常不一定是「失敗」,但可用作通過堆棧向上傳播狀態更改的方式。 – AndyT

+0

@Aizaz:*抓住它! – EJP

4

首先,readObject()如果您在創建時寫道null到流只返回null。如果數據流中沒有更多數據,則會拋出一個EOFException

如果您不希望EOF,原因可能是該流已損壞。如果在向其寫入數據後忘記關閉它,可能會發生這種情況。

+0

那麼如何檢測我們在文件結尾?我的意思是如何避免EOF異常? –

+4

@Aizaz:EOFException告訴你。檢查異常意味着被捕獲並檢查控制流。它們不是錯誤,而是附加的返回碼。有時。如果使用正確。大多數IOExceptions並非如此。但是對於EOFException是正確的。 ......啊哈。另一種解決方案是在對象之前將對象的數量寫入流中,以便循環已知次數。或者將對象放置在容器中,如列表或數組,然後裝入容器。 –

+0

我認爲這是正確的答案:@Aizaz - readObject()會一次讀取整個文件併爲您反序列化它。只要確保你只調用一次而不是循環。 - adarshr 18小時前 –

5

我有同樣神祕的EOFException,它只是對象類的路徑通過ObjectOutputStream發送到ObjectInputStream。它們必須具有相同的路徑(相同的軟件包名稱,當然還有相同的類名)。