2012-12-28 35 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

相关问题