ver una tabla studio ruta mostrar insertar imagen guardar datos consultas android sqlite cursor blob protocol-buffers

una - Recuperar gran blob de la base de datos sqlite de Android



select sqlite android studio (2)

Almacené trozos de datos binarios (protobufs) en la base de datos sqlite de una aplicación de Android sin darme cuenta de que el Cursor de Android solo puede contener un máximo de 1 MB de datos. Ahora sé que debería haber almacenado estos blobs binarios en archivos y solo hacer referencia a los archivos en las entradas de la base de datos sqlite.

Necesito actualizar la base de datos (la aplicación ha estado en uso por un tiempo) para mover estos fragmentos binarios a archivos. El problema es que los datos de algunos usuarios ya pueden haber excedido el límite de 1 MB y no puedo recuperarlos de la base de datos (al acceder al Cursor resultante para una sola fila que contiene un blob grande se IllegalStateException: Couldn''t read row 0, col 0 from CursorWindow. Make sure the Cursor is initialize before accessing data from it una IllegalStateException: Couldn''t read row 0, col 0 from CursorWindow. Make sure the Cursor is initialize before accessing data from it .

¿Cómo recupero los blobs binarios que son mayores que el límite del Cursor 1MB que se han almacenado en la base de datos sqlite?


CL. La respuesta será solo con blobs <5MB. Si intentó usarlo con burbujas de más de 5 megabytes, seguirá obteniendo la excepción. Para obtener grandes blobs necesitas usar una biblioteca llamada sqlite4java que usa llamadas nativas a la base de datos sin usar cursores. Este es un ejemplo del uso de esta biblioteca para obtener un blob grande:

SQLiteConnection sqLiteConnection=null; SQLiteStatement sqLiteStatement=null; try { File databaseFile = context.getDatabasePath("database.db"); sqLiteConnection=new SQLiteConnection(databaseFile); sqLiteConnection.open(); sqLiteStatement=sqLiteConnection.prepare("SELECT blob FROM table WHERE id=?"); sqLiteStatement.bind(1, id); sqLiteStatement.step(); byte[] blob=sqLiteStatement.columnBlob(0); } finally { if(sqLiteStatement!=null) sqLiteStatement.dispose(); if(sqLiteConnection!=null) sqLiteConnection.dispose(); }


Puedes leer grandes manchas en pedazos. Primero averigua cuales necesitan este tratamiento:

SELECT id, length(blobcolumn) FROM mytable WHERE length(blobcolumn) > 1000000

y luego leer trozos con substr :

SELECT substr(blobcolumn, 1, 1000000) FROM mytable WHERE id = 123 SELECT substr(blobcolumn, 1000001, 1000000) FROM mytable WHERE id = 123 ...

También puede compilar su propia copia de SQLite y acceder a las funciones de E / S de flujo BLOB o las funciones de consulta normales de la API de C con el NDK, pero eso sería demasiado complejo en este caso.