2014-03-19 36 views
1

嗨我需要讀取字節數組作爲對象。然而每當我嘗試打印出Stream CorruptedException。當讀取對象時發生StreamCorrupedException

下面是我寫的代碼

public class TestSave { 
    public static void main(String[] args) { 
     String key = "redismap"; 
     Map<String, Object> map = new HashMap<String, Object>(); 
     List<String> list = new ArrayList<String>(); 

     map.put("String", "test"); 
     map.put("List", list); 

     ObjectOutputStream oos = null; 
     ByteArrayOutputStream bos = null; 

     JedisHelper helper = JedisHelper.getInstacne(); 
     Jedis connection = helper.getConnection(); 

     try{ 
      bos = new ByteArrayOutputStream(); 
      oos = new ObjectOutputStream(bos); 
      oos.writeObject(map); 
      byte[] value = bos.toByteArray();   
      oos.close(); 
      connection.set(key.getBytes(), value); 
     }catch(Exception e){e.printStackTrace();} 
     helper.returnResource(connection); 
     helper.destroyPool(); 
     System.out.println("DONE!"); 
    } 
} 

那麼,這是讀碼

public class TestWithdaw { 
    public static void main(String[] args) { 
     JedisHelper helper = JedisHelper.getInstacne(); 
     Jedis connection = helper.getConnection(); 
     String key = "redismap"; 
     String result = connection.get(key); 
     byte[] primalData = result.getBytes(); 
     System.out.println("Byte Arrays : " + Arrays.toString(primalData)); 

     ByteArrayInputStream bis = null; 
     ObjectInputStream ois = null; 

     try{ 
      bis = new ByteArrayInputStream(primalData); 
      ois = new ObjectInputStream(bis); 
      Object resultMap = ois.readObject(); 

      System.out.println("resultMap : " + resultMap); 
      ois.close(); 
     }catch(Exception e){e.printStackTrace();} 
     helper.returnResource(connection); 
     helper.destroyPool(); 
    } 
} 

然後,這是我得到的錯誤消息。

java.io.StreamCorruptedException: invalid stream header: EFBFBDEF 
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804) 
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299) 
    at org.owls.redis.test.TestWithdaw.main(TestWithdaw.java:28) 

我不明白這個流頭有什麼問題。 這些都是我已經試過: - <

  1. 改變列表以矢量編寫代碼。 (串行問題)

感謝您幫助我:d

+0

如果在'bos.toByteArray'之前調用'oos.close',會發生什麼? – immibis

+0

'ObjectOutputStream'被緩衝!您需要在檢索數據前調用'flush()'(或'close()')__。 –

+0

@immibis同樣的結果。它仍然顯示StreamCorruptedException。 –

回答

2

我認爲問題出在你的序列化的字節的存儲和檢索 - 執行序列化的代碼和deserialisation本身就是罰款。

沒有中間儲存,代碼工作,如下所示:

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(bos); 
    oos.writeObject(map); 
    byte[] value = bos.toByteArray(); 
    oos.close(); 

    for (byte b : value) 
    { 
    System.out.print(Integer.toHexString(0xff & b) + " "); 
    } 
    System.out.println(""); 

    final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(value)); 
    final Object read = ois.readObject(); 

    System.out.println("read: " + read); 

這產生:

交流ED 0 5 73 72 0 11 6A 61 76 61 2E 75 74 69 6C 2e 48 61 73 68 4d 61 70 5 7 da c1 c3 16 60 d1 3 0 2 46 0 a 6c 6f 61 64 46 61 63 74 6f 72 49 0 9 74 68 72 65 73 68 6f 6c 64 78 70 3f 40 0 0 0 0 0 c 77 8 0 0 0 10 0 0 0 2 74 0 6 53 74 72 69 6e 67 74 0 4 74 65 73 74 74 0 4 4c 69 73 74 73 72 0 13 6a 61 76 61 2e 75 74 69 6c 2e 41 72 72 61 79 4c 69 73 74 78 81 d2 1d 99 c7 61 9d 3 0 1 49 0 4 73 69 7a 65 78 70 0 0 0 0 77 4 0 0 0 0 78 78

讀:{名單= [],字符串=測試}

你會看到,我們找到了字節流的開始是ac ed 00 05 73,這是下面的Java對象序列化規範常量:

  • STREAM_MAGIC
  • STREAM_VERSION
  • TC_OBJECT

因此,您的調查應該關注爲什麼您的原始數據與最初生成的數據不匹配。


讓我們繼續這個方向(免責聲明:我從來沒有使用過Redis)......

您使用此代碼從Redis的取回數據:

String key = "redismap"; 
String result = connection.get(key); 
byte[] primalData = result.getBytes(); 

在這裏,你取回數據作爲Java String,然後使用Java VM的默認編碼方案獲得的字節數。這與Redis使用的編碼表示可能有所不同。

爲什麼不使用返回byte[]的版本?這將是:

String key = "redismap"; 
byte[] primalData = connection.get(key.getBytes()); 

這很可能是在任何Stringbyte[]編碼和解碼一致。

+0

非常感謝。其實,我擔心字符編碼集的關鍵。但是,當我按照你的建議將參數從字符串更改爲字節[]時,它的效果非常好。再次感謝:D –

+0

@greg當我們在Redis數據存儲中使用ISO-8859-1編碼時,類似的事情發生在我們身上。最後把所有東西都轉換成byte [],現在一切正常。謝謝你的回答給了我幾個指示來調試。 – Peeyush

相關問題