Java,JDBC:尝试从数据库中检索对象时出现StreamCorruptedException

时间:2012-12-28 19:00:26

标签: java jdbc

我在从数据库中正确检索我自己的类“BallotPaper”的特定对象时遇到问题。它可以正常保存,但在创建ObjectInputStream时会抛出异常。

当然,我在这里阅读了许多类似的问题和答案,但仍然无法处理。

在数据库中,我有一个包含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();

Exception在最后一行抛出,标有*。

看起来像是:

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)

感谢您的所有答案。

2 个答案:

答案 0 :(得分:0)

添加flush()

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

允许ObjectOutputStream缓冲其输出。您也可以拨打close()而不是flush(),这至少会表明您不应该再次使用这些流。

答案 1 :(得分: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);

检索方式不会改变。