2013-02-23 55 views
1

將對象寫入ByteArrayOutputStream時,出現了一些奇怪的結果。期待writeObject(null)後的0個字節,而我找到5個字節,這是怎麼回事?

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ObjectOutputStream os = new ObjectOutputStream(baos); 
    os.writeObject(null); 

    byte[] objectBytes = baos.toByteArray(); 
    int objectSize = objectBytes.length; 

所以我寫了一個零到一個ByteArrayOutputStream,然後當我從這個流中檢索字節而不是找到0字節,我發現有5字節的值如下 -

  • [0] => -84
  • [1] => -19
  • [2] => 0
  • [3] => 5
  • [4] => 112

如果我改變os.writeObject(null)os.writeObject("A")我得到8個字節,它們是 -

  • [0] => -84
  • [1] => -19
  • [2] = > 0
  • [3] => 5
  • [4] => 116
  • [5] => 0
  • [6] => 65
  • [7] => 8

所以,這是怎麼回事就在這裏,如果我寫0字節我希望找到的字節,當我檢索字節數組。然後我看到它增加了一個額外的5個字節。所以當我寫「A」時,我期望它在字節數組中返回6個字節,但它返回8.這裏發生了什麼?

+1

你爲什麼期望零字節?如何在不使用任何字節的情況下傳輸對象引用值'null'?這個問題沒有開始有意義。 – EJP 2013-02-23 22:41:21

回答

10

首先,當您編寫null時,您不會寫任何內容。你正在寫一個空值。序列化過程必須確保當你將反序列化時,你會得到一個null回來,所以它必須以某種方式表示。在開始標記流的開始時可能還有開銷。

當你寫「A」的時候,你也不只是放上「A」字符。你正在序列化一個完整的String對象。這必須包含反序列化程序以後重新生成具有相同值的String對象的信息。所以有類型信息和內容。內容本身也需要多於一個字節,因爲Java在內部將String表示爲數組char,這是2字節的值,並且還因爲字符串的長度必須以某種方式進行編碼(實際上我甚至感到驚訝他們會把所有這些都放在8個字節中)。

編輯:我看了一下關於this page的解釋。我們可以使用它來了解您獲得的結果。

在第一個例子,你有以下字節:

  • AC ED(這是hexadecimalese爲-84 -19):STREAM_MAGIC。一個魔術值,指定這是一個序列化協議。
  • 00 05:STREAM_VERSION。版本5。
  • 70(十六進制爲112):TC_NULL,表示一個空值。

在你的第二個例子,實際上你給不對應的值。我曾嘗試你的代碼,我自己和我得到的是:

  • AC ED:STREAM_MAGIC
  • 00 05:STREAM_VERSION
  • 74:TC_STRING,代表一個新的String
  • 00 01:字符串的長度(1)
  • 65: 「A」 的UTF8表示。

對於最後一個字節,我顯然有點不對勁:即使Java的內部採用的是2個字節表示一個字符,它編碼字符串UTF8,僅使用一個字符「A」的字節。

所有格式的特殊值在類中的常量ObjectStreamConstants

2

空是像任何其他的值。可能有些情況需要寫入。

相關問題