2012-10-03 16 views
17

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

Necesito actualizar la base de datos (la aplicación ha estado en uso por un tiempo) para mover estos fragmentos binarios a los archivos. El problema es que los datos de algunos usuarios pueden haber excedido ya el límite de 1 MB y no puedo recuperarlos de la base de datos (accediendo al resultado Cursor para una sola fila que contiene un blob grande arroja un 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 de 1MB Cursor que se han almacenado en la base de datos sqlite?

+0

¡Hola, gracias! ¡Esta pregunta me ayudó a analizar y resolver el mismo problema al que me enfrentaba! –

Respuesta

27

Puede leer manchas grandes en piezas. En primer lugar averiguar cuáles necesitan este tratamiento:

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

y luego leyó 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 acceso a cualquiera de los BLOB stream I/O funciones o la funciones de consulta normales de la API C con el NDK, pero eso sería demasiado complejo en este caso.

+0

¡Muchas gracias! Esto realmente ayudó. No tenía idea acerca de las funciones básicas de SQLite. Funcionó a la perfección! – ashughes

+0

¿Tiene alguna forma eficiente de agregar esos fragmentos para formar un 'byte []' completo? –

+0

@KamranAhmed Ya conoce toda la longitud, así que asigne una gran matriz y copie los trozos. –

0

CL. la respuesta será solo con blobs < 5MB. Si intentas usarlo con manchas de más de 5 megabytes, aún obtendrás la excepción. Para buscar blobs grandes, debe usar una biblioteca llamada sqlite4java que usa llamadas nativas a la base de datos sin usar cursores. Aquí hay 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(); 
} 
Cuestiones relacionadas