DB query returns corrupted data on Android
I have an SQLite DB with a sample table, which is stored in the assets/ folder.
This DB contains a single table, one of the columns is BLOB containing a BMP image. I may read/write this image flawlessly using JDBC on the host machine.
Then the data is accessed from the emulator using the following code:
final Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null, null, null);
if (cursor.moveToFirst()) {
byte[] icon = cursor.getBlob(cursor.getColumnIndex(SearchEngines.ICON));
// ...
But the attempt to decode retreived image fails:
final Bitmap icon = BitmapFactory.decodeByteArray(icon , 0, icon.length);
I get null result and the following in the log:
DEBUG/skia(374): --- decoder->decode returned false
After this, I dumped the blob array into the file and compared with the original image. And it was a complete surprise, because the only uncovered difference was that all the 0x00 bytes were replaced with 0x25 0x30 sequences in the retreived blob:
0x00 -> 0x25 0x30 // %0
Besides that, all the data was intact. What the heck?
Update 1. After pulling the DB from the emulator (adb pull) the data it contains is corrupted (same %0 symbols). So, the problem is either in DB itself or implementation/usage of query/getBlob or other DB access code.
Update 2. *Seems that it's wrong* As far as I understand, SQLite supports 2 ways of storing large objects: TEXT and BLOB. TEXT columns don't contain 0x00 bytes, and in BLOBs 0x00 is translated into %0 (what a coincidence!). So, it seems that what I get is internal representation, not the actual data.
Update 3. Code for adding to DB is the following:
private void save(Connection conn, String id, String fileName) throws SQLException, IOExc开发者_JAVA技巧eption {
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();
}
精彩评论