2012-10-03 19 views
17

Ho memorizzato blocchi di dati binari (protobuf) nel database sqlite di un'app Android senza rendersi conto che il numero di telefono Cursor di Android può contenere solo un massimo di 1 MB di dati. Ora so che avrei dovuto memorizzare questi blob binari nei file e ho fatto riferimento ai file nelle voci del database SQLite.Recupera blob di grandi dimensioni dal database sqlite di Android

Ho bisogno di aggiornare il database (l'app è in uso da un po 'di tempo) per spostare questi blocchi binari in file. Il problema è che alcuni dati dell'utente potrebbero aver già superato il limite di 1 MB e non sono in grado di recuperarlo dal database (accedendo allo Cursor risultante per una singola riga che contiene un blob di grandi dimensioni genera un IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialize before accessing data from it).

Come si recuperano i BLOB binari superiori al limite di 1MB Cursor che sono stati memorizzati nel database sqlite?

+0

Ehi, grazie! Questa domanda mi ha aiutato ad analizzare e risolvere lo stesso problema che stavo affrontando! –

risposta

27

È possibile leggere frammenti di grandi dimensioni in pezzi. In primo luogo scoprire quali hanno bisogno di questo trattamento:

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

e poi leggere pezzi con substr:

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

Si potrebbe anche compilare il proprio copia di SQLite e accesso sia le BLOB stream I/O funzioni o le normali funzioni di interrogazione dell'API C con NDK, ma in questo caso sarebbe troppo complesso.

+0

Grazie mille! Questo mi ha davvero aiutato. Non avevo idea delle funzioni di base di SQLite. Ha funzionato perfettamente! – ashughes

+0

Avete un modo efficace per aggiungere quei blocchi per creare un intero byte [] '? –

+0

@KamranAhmed Conoscete già l'intera lunghezza, quindi assegnate una grande matrice e copiate i blocchi. –

0

CL. la risposta sarà solo con BLOB < 5 MB. Se hai provato ad usarlo con BLOB di dimensioni superiori a 5 megabyte, otterrai comunque l'eccezione. Per recuperare blob di grandi dimensioni è necessario utilizzare una libreria denominata sqlite4java che utilizza le chiamate native al database senza utilizzare i cursori. Ecco un esempio di utilizzo di questa libreria per recuperare un blob di grandi dimensioni:

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(); 
} 
Problemi correlati