2017-02-04 76 views
0

我有一些我不明白,請幫助。ByteArrayInputStream到ObjectInputStream消失

System.out.println("\n" + Arrays.toString(buffer) + "\n"); 
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available()); 
ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(buffer)); 
System.out.println("input.available(): " + input.available()); 

其輸出低於:

[-84, -19, 0, 5] 

buffer.length = 4 
new ByteArrayInputStream(buffer).available() is: 4 
input.available(): 0 

我很困惑,爲什麼4個的有效字節一個字節數組,投入的ObjectInputStream後,就變成零。

事情我已經嘗試:

  1. 起初,我懷疑我的字節數組是空的,但正如你看到的,我打印出來,其長度爲4
  2. 後來我想我的字節可能無效,所以我打印出每個字節,如你所見,這四個字節都是有效的。

因此,我迷失了爲什麼會發生這種情況。

請幫助,非常感謝!

+0

什麼是輸入數據?在4個字節處,它似乎不太可能是一個對象。正如文檔所說,「ObjectInputStream反序列化先前使用ObjectOutputStream寫入的原始數據和對象。」 –

+0

如何顯示輸入?我認爲Arrays.toString(緩衝區)是我能展示的最好的。 – FisherCoder

+0

所以在我以前的評論中有這個問題:'先前使用ObjectOutputStream編寫的數據和對象'。你不這樣做。您正在讀取從未通過「ObjectInputStream」的原始字節。 –

回答

3

正如提到的其他答案,available僅表示在發生阻塞之前可以讀取的字節數。

這是我的猜想,但是,你沒有按照ObjectInputStream,其指定An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

換句話說規則,實際上爲了與ObjectInputStream讀取數據,你首先必須有書面的該數據使用某種ObjectOutputStream。這裏是顯示這個與你提供的數據爲例:(我要補充一點,我很少與IO在Java中工作,因此上述可能不是最好的做法或有多餘的代碼)

byte[] buffer = new byte[]{-84,-19,0,5}; 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
ObjectOutputStream objectOutputStream= new ObjectOutputStream(out); 
objectOutputStream.write(buffer); 
objectOutputStream.flush(); 

ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); 
System.out.println("input.available(): " + input.available()); 
System.out.println("input.readByte(): " + input.readByte()); 

+0

感謝您指出,它絕對加深了我的理解!^^ – FisherCoder

1

Hereavailable方法的javadoc的,這就是它說:

返回可以無阻塞地讀取的字節數。

所以,它不會返回bytes目前總數數組中/讀,它返回的bytes它可以被阻塞之前閱讀次數。所以,它返回0是一個有效的場景。

現在,讓我們來看看ObjectInputStream javadoc的,這裏是簡要說明:

非對象讀取超出分配的數據到底會 反映的數據以同樣的方式結束他們會指示 流的結束:字節讀取將返回-1作爲字節讀取或 讀取的字節數,原語讀取將拋出EOFExceptions。如果 沒有相應的writeObject方法,則默認的 序列化數據結束標記分配數據的結束。

什麼你想在你的代碼做的是read原始數據(或讀不WriteObject法),因爲它是無效的數據(ObjectInputStreamread總是返回-1。我只能通過調用readObject方法來重現EOFException

我又試圖寫入/讀取一個新的對象和測試available方法調用,看看下面的代碼片段:

byte[] buffer = new byte[]{-84, -19, 0, 5}; 
System.out.println("\n" + Arrays.toString(buffer) + "\n"); 
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); 
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available()); 
ObjectInputStream input = new ObjectInputStream(byteArrayInputStream); 
System.out.println("input.available(): " + input.available()); 
//  System.out.println(input.readObject()); //Uncomment to see EOFException 

Date date = new Date(); 
System.out.println(date); 
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 
ObjectOutputStream out = new ObjectOutputStream(byteArrayOut); 
out.writeObject(date); 
byte[] bytes = byteArrayOut.toByteArray(); 

input = new ObjectInputStream(new ByteArrayInputStream(bytes)); 
System.out.println(input.available()); 
System.out.println(input.readObject()); 

代碼reads已經寫對象,並輸出值。請注意,即使它正確讀取對象並打印相同的對象,available方法仍會返回0。所以,我建議不要過於依賴available,因爲它是誤導性的名稱:)