提问人:Ande Hofer 提问时间:3/3/2012 最后编辑:Ande Hofer 更新时间:3/5/2012 访问量:793
ObjectInputStream 适用于 MySql,但不适用于 sqlite
ObjectInputStream works for MySql, but not for sqlite
问:
我使用此代码从 MySql 数据库中获取 Blob,它工作正常,当我将其用于 sqlite 数据库时,它会抛出 StreamCorruptedException
public static SessionData getIvissSession(BigInteger id) throws IvissDatabaseException {
SessionData sd = null;
PreparedStatement pstmt = null;
Connection con = null;
try {
con = getConnection();
pstmt = con.prepareStatement("SELECT ivissblob FROM iviss_session_table WHERE id =?");
pstmt.setLong(1, Long.parseLong(id.toString()));
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
byte[] ivissblob = rs.getBytes("ivissblob");
ObjectInputStream objectIn = new ObjectInputStream(new ByteArrayInputStream(ivissblob));
sd = (SessionData) objectIn.readObject();
objectIn.close();
}
} catch (SQLException e) {
throw new IvissDatabaseException(Constants.ERROR_202);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return sd;
当我使用 SqLite 数据库时:
java.io.StreamCorruptedException:无效的流标头:61742E75 在 java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:797) 在 java.io.ObjectInputStream。(ObjectInputStream.java:294)
为什么会有不同的行为?
以下是我如何写入数据库:
public static void insertIntoTable(BigInteger id, SessionData sd, byte[] rtsd, IvissWorker ivissWorker) {
PreparedStatement pstmt = null;
Connection con = null;
try {
con = getConnection();
pstmt = con
.prepareStatement("REPLACE INTO iviss_session_table (id, ivissblob, rtblob, lastaccess) VALUES(?,?,?,?)");
pstmt.setLong(1, Long.parseLong(id.toString()));
pstmt.setObject(2, sd);
pstmt.setObject(3, rtsd);
pstmt.setDate(4, new Date(System.currentTimeMillis()));
pstmt.executeUpdate();
} catch (SQLException e) {
ivissWorker.getIvissWorkerOutputHandler().addError(Constants.ERROR_205, "", DbConfiguration.getDbUri());
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
附加信息 sqlite 驱动程序版本:
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
答:
1赞
Ande Hofer
3/5/2012
#1
同事给出的问题解决方案:
不要使用 .setObject 方法插入对象,而是使用 .setBytes 插入对象。
public static void insertIntoTable(BigInteger id, SessionData sd, byte[] rtsd, IvissWorker ivissWorker) {
PreparedStatement pstmt = null;
Connection con = null;
try {
con = getConnection();
pstmt = con
.prepareStatement("REPLACE INTO iviss_session_table (id, ivissblob, rtblob, lastaccess) VALUES(?,?,?,?)");
pstmt.setLong(1, Long.parseLong(id.toString()));
pstmt.setBytes(2, IvissUtil.getBytes(sd));
pstmt.setObject(3, rtsd);
pstmt.setDate(4, new Date(System.currentTimeMillis()));
pstmt.executeUpdate();
// System.out.println("Stored/Replaced session with ID: " + id +
// " in table.");
} catch (SQLException e) {
ivissWorker.getIvissWorkerOutputHandler().addError(Constants.ERROR_205, "", DbConfiguration.getDbUri());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
和 getBytes 方法:
public static byte[] getBytes(Object obj) throws java.io.IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
oos.close();
bos.close();
byte[] data = bos.toByteArray();
return data;
}
现在它适用于 sqlite 和 MySql
评论
Blob blob = rs.getBlob("ivissblob"); ObjectInputStream objectIn = new ObjectInputStream(new ByteArrayInputStream(blob.getBinaryStream()));