Запрос БД возвращает поврежденные данные на Android - PullRequest
1 голос
/ 13 марта 2011

У меня есть БД 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...