У меня есть БД SQLite с образцом таблицы, которая хранится в папке assets /.
Эта БД содержит одну таблицу, одним из столбцов которой является BLOB, содержащий изображение BMP. Я могу безупречно читать / писать этот образ, используя 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);
Я получаю нулевой результат и следующее в журнале:
DEBUG/skia(374): --- decoder->decode returned false
После этого я поместил массив BLOB-объектов в файл и сравнил его с исходным изображением. И это было полной неожиданностью, потому что единственное обнаруженное различие состояло в том, что все 0x00 байтов были заменены на 0x25 последовательностей 0x30 в полученном BLOB-объекте:
0x00 -> 0x25 0x30 // %0
Кроме того, все данные были целы. Какого черта?
Обновление 1. После извлечения БД из эмулятора (adb pull) содержащиеся в нем данные повреждены (те же символы% 0). Таким образом, проблема заключается либо в самой БД, либо в реализации / использовании query / 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();
}