2009-12-23 13 views
6

Il database della mia applicazione deve essere riempito con molti dati, quindi durante il onCreate(), non sono solo alcune istruzioni di creazione tabella sql , ci sono molti inserti. La soluzione che ho scelto è di memorizzare tutte queste istruzioni in un file sql che si trova in res/raw e che viene caricato con Resources.openRawResource(id).Creazione di un'app per Android Database con una grande quantità di dati

Funziona bene, ma mi trovo di fronte al problema di codifica, ho accentuato i caratteri canel file sql che appare male nella mia applicazione. Questo mio codice per fare questo:

public String getFileContent(Resources resources, int rawId) throws 
IOException 
    { 
    InputStream is = resources.openRawResource(rawId); 
    int size = is.available(); 
    // Read the entire asset into a local byte buffer. 
    byte[] buffer = new byte[size]; 
    is.read(buffer); 
    is.close(); 
    // Convert the buffer into a string. 
    return new String(buffer); 
    } 

public void onCreate(SQLiteDatabase db) { 
    try { 
     // get file content 
     String sqlCode = getFileContent(mCtx.getResources(), R.raw.db_create); 
     // execute code 
     for (String sqlStatements : sqlCode.split(";")) 
     { 
      db.execSQL(sqlStatements); 
     } 

     Log.v("Creating database done."); 
     } catch (IOException e) { 
      // Should never happen! 
      Log.e("Error reading sql file " + e.getMessage(), e); 
      throw new RuntimeException(e); 
     } catch (SQLException e) { 
      Log.e("Error executing sql code " + e.getMessage(), e); 
      throw new RuntimeException(e); 
     } 

La soluzione che ho trovato per evitare questo è quello di caricare le istruzioni SQL da un enorme static final String invece di un file, e tutti i caratteri accentuati apparire bene.

Ma non c'è un modo più elegante per caricare le istruzioni sql di un grande attributo static final String con tutte le istruzioni sql?

risposta

8

Credo che il problema è in questa linea:

return new String(buffer); 

si sta convertendo la matrice di byte in una java.lang.String ma non stiamo dicendo Java/Android la codifica da utilizzare. Quindi i byte per i tuoi caratteri accentati non vengono convertiti correttamente poiché viene utilizzata la codifica errata.

Se si utilizza il costruttore String(byte[],<encoding>), è possibile specificare la codifica del file e i caratteri verranno convertiti correttamente.

+0

Grazie mille Dave – tbruyelle

4

La soluzione di file SQL sembra perfetta, è solo che è necessario assicurarsi che il file venga salvato nella codifica utf8 altrimenti tutti i caratteri accentuati andranno persi. Se non si desidera modificare la codifica del file, è necessario passare un argomento aggiuntivo al nuovo String(bytes, charset) che definisce la codifica del file.

Preferisco utilizzare le risorse file anziché la stringa finale statica per evitare di caricare tutti quei byte non necessari in memoria. Nei telefoni cellulari vuoi salvare tutta la memoria possibile!

-1

Sembra che si passino tutte le istruzioni SQL in una stringa. Questo è un problema perché execSQL si aspetta "una singola istruzione che non sia una query" (vedi documentazione [qui] [1]). Di seguito è una soluzione un po 'brutta ma funzionante.

ho tutti i miei istruzioni SQL in un file in questo modo:

INSERT INTO VALUES Tabella 1 (1, 2, 3);

INSERIRE NELLA tabella 1 VALORI (4, 5, 6);

INSERIRE NELLA tabella 1 VALORI (7, 8, 9);

Avviso le nuove linee tra il testo (punto e virgola seguito da 2 nuove linee) allora, faccio questo:

String text = new String(buffer, "UTF-8"); 
for (String command : text.split(";\n\n")) { 
    try { command = command.trim(); 
    //Log.d(TAG, "command: " + command); 
    if (command.length() > 0) 
     db.execSQL(command.trim()); 
} 
catch(Exception e) {do whatever you need here} 

mie colonne di dati contengono macchie di testo con nuove linee e punti e virgola, così io dovevo trovare un diverso comando-separatore.Assicurati di essere creativo con lo split str: usa qualcosa che sai che non esiste nei tuoi dati.

HTH Gerardo

[1]: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String, java.lang.Object [])

+0

Anche io faccio uno split (";"), e il mio problema non riguardava le istruzioni SQL ma i caratteri di codifica. – tbruyelle

1

Sto usando un approccio diverso: invece di eseguire carichi di istruzioni SQL (che ci vorrà molto tempo per completare), costruisco il mio database sqlite sul desktop, lo metto nella cartella delle risorse, creo un db sqlite vuoto in Android e copi il db dalla cartella delle risorse nella cartella del database. Questo è un enorme aumento di velocità. Nota, devi prima creare un database vuoto in Android, e poi puoi copiarlo e sovrascriverlo. In caso contrario, Android non ti consentirà di scrivere un db nella cartella del database. Ci sono diversi esempi su internet. BTW, sembra che questo approccio funzioni meglio, se il db non ha estensione di file.

+0

puoi condividere il codice che hai usato? –

Problemi correlati