2012-12-28 98 views
-1

我在從數據庫中正確檢索自己的類「BallotPaper」的特定對象時遇到問題。它可以正確保存,但在創建ObjectInputStream時會引發異常。嘗試從數據庫中檢索對象時出現Java,JDBC:StreamCorruptedException

當然,我已經閱讀了許多類似的問題和答案,但仍然無法處理它。

在數據庫中我有一個bytea類型的列(它是postgreSQL),我保存我的對象。

下面是幾行代碼:

//Saving the object 'paper' of the class 'BallotPaper' 
    PreparedStatement st = connection.prepareStatement(query); 
    ByteArrayOutputStream byos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(byos); 
    oos.writeObject(paper); 
    byte[] bytePaper = byos.toByteArray(); 
    st.setBytes(1, bytePaper); 
    st.executeUpdate(); 

    byos.close(); 
    oos.close(); 
    st.close(); 

//Trying to retrieve the object: 
    String query2 = "SELECT paper FROM voters WHERE id="+_id+";"; 
    Statement s = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 
    ResultSet r = s.executeQuery(query2); 
    r.first(); 
    bytePaper = r.getBytes(1); 
    ByteArrayInputStream b = new ByteArrayInputStream(bytePaper); 
    ObjectInputStream o = new ObjectInputStream(b); // * 
    BallotPaper ba = (BallotPaper)o.readObject(); 

拋出異常,最後前行,標有*。

它看起來像:

java.io.StreamCorruptedException: invalid stream header: BB656430 
at java.io.ObjectInputStream.readStreamHeader(Unknown Source) 
at java.io.ObjectInputStream.<init>(Unknown Source) 
at slave.VotersDB.saveFilledPaper(VotersDB.java:162) 
at slave.ClientThread.prepareResponse(ClientThread.java:50) 
at slave.ClientThread.run(ClientThread.java:72) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

感謝所有的答案。

回答

0

添加flush()

oos.writeObject(paper); 
oos.flush(); 
byte[] bytePaper = byos.toByteArray(); 

ObjectOutputStream允許緩衝其輸出。你也可以調用close()而不是flush(),這至少可以清楚地表明你不應該再次使用流。

+0

不幸的是,它不適用於flush()。 保存後,我關閉了所有的流。 – brzeszczot

0

我終於設法解決了這個問題。它證明不適合保存二進制數據以使用setBytes()方法。相反,應該使用setBinaryStream()。

第一種方法中,序列化對象的字節與原始字符完全不同。任何人都知道爲什麼?

下面是正確的代碼:

PreparedStatement st = connection.prepareStatement(query);  

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(baos); 
oos.writeObject(paper); 
byte[] bytePaper = baos.toByteArray(); 

PipedInputStream pis = new PipedInputStream(); 
PipedOutputStream pos = new PipedOutputStream(pis); 
pos.write(bytePaper); 
pos.flush(); 

st.setBinaryStream(1, pis,bytePaper.length); 

檢索的方式不會改變。

+0

您要插入的列的類型是什麼?它是'BINARY','VARBINARY','RAW'還是'BLOB'?或者它是一種字符類型? – parsifal

相關問題