-1

データベースから自分のクラス「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();

例外は、 * でマークされた最後の前の行でスローされます。

次のようになります。

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)

すべての回答に感謝します。

4

2 に答える 2

0

を追加しflush()ます:

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

はそのObjectOutputStream出力をバッファリングすることができます。close()または、ではなく呼び出すこともできますflush()。これにより、少なくともストリームを再度使用するべきではないことが明確になります。

于 2012-12-28T19:13:09.090 に答える
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);

取り出し方は変わりません。

于 2012-12-29T10:00:40.810 に答える