我有一个带有示例表的SQLite DB,它存储在assets /文件夹中。
此DB包含单个表,其中一列是包含BMP图像的BLOB。我可以在主机上使用JDBC完美地读/写这个图像。
然后使用以下代码从仿真器访问数据:
final Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null, null, null);
if (cursor.moveToFirst()) {
byte[] icon = cursor.getBlob(cursor.getColumnIndex(SearchEngines.ICON));
// ...
但尝试解码后退图像失败了:
final Bitmap icon = BitmapFactory.decodeByteArray(icon , 0, icon.length);
我在日志中得到null结果和以下内容:
DEBUG/skia(374): --- decoder->decode returned false
在此之后,我将blob数组转储到文件中并与原始图像进行比较。这是一个完全的惊喜,因为唯一未发现的差异是所有0x00字节都被替换为了翻转blob中的0x25 0x30序列:
0x00 -> 0x25 0x30 // %0
除此之外,所有数据都完好无损。到底是什么?
更新1。从仿真器(adb pull)拉出数据库后,其中包含的数据已损坏(相同的%0符号)。因此,问题出在数据库本身或查询/ getBlob或其他数据库访问代码的实现/使用。
更新2。 * 似乎错了 *据我了解,SQLite支持2种存储大型对象的方式:TEXT和BLOB。 TEXT列不包含0x00字节,在BLOB中0x00被转换为%0(这是巧合!)。所以,我得到的是内部表示,而不是实际数据。
更新3。添加到数据库的代码如下:
private void save(Connection conn, String id, String fileName) throws SQLException, IOException {
final String sql = "UPDATE " + TABLE_NAME + " SET " + BLOB_COLUMN_NAME + " = ? WHERE " + ID_COLUMN_NAME + " = ?";
System.out.println("Executing: " + sql);
final PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(2, Integer.valueOf(id));
File fBlob = new File(fileName);
FileInputStream is = new FileInputStream(fBlob);
byte[] bytes = new byte[(int) fBlob.length()];
int rc = is.read(bytes);
assert (rc == bytes.length);
System.out.println("Total size: " + rc);
pstmt.setBytes(1, bytes);
pstmt.execute();
}