2009-12-23 11 views
6

la base de datos de mi solicitud se tienen que cubrir con una gran cantidad de datos, por lo que durante onCreate(), es no sólo algunos crean tabla de SQL instrucciones, hay una gran cantidad de inserciones. La solución que elegí es almacenar todas estas instrucciones en un archivo sql ubicado en res/raw y que está cargado con Resources.openRawResource(id).Creación de base de datos de aplicaciones androide con gran cantidad de datos

Funciona bien pero tengo problemas de codificación, tengo algunos caracteres acentuados en el archivo sql que parece malo en mi aplicación. Este mi código para hacer esto:

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 solución que encontré para evitar esto es cargar las instrucciones SQL de una enorme static final String en lugar de un archivo y todos los caracteres acentuados parece bien.

¿Pero no hay una manera más elegante de cargar instrucciones sql que un gran atributo static final String con todas las instrucciones sql?

Respuesta

8

Creo que su problema es en esta línea:

return new String(buffer); 

va a convertir la matriz de bytes a un java.lang.String pero no estás diciendo Java/Android la codificación a utilizar. Por lo tanto, los bytes de los caracteres acentuados no se convierten correctamente a medida que se utiliza la codificación incorrecta.

Si utiliza el constructor String(byte[],<encoding>), puede especificar la codificación que tiene su archivo y sus caracteres se convertirán correctamente.

+0

Muchas gracias a Dave – tbruyelle

4

La solución de archivos SQL parece perfecta, solo es necesario que se asegure de que el archivo se guarde en la codificación utf8, de lo contrario, se perderán todos los caracteres acentuados. Si no desea cambiar la codificación del archivo, debe pasar un argumento adicional al nuevo String(bytes, charset) definiendo la codificación del archivo.

Prefiere utilizar recursos de archivos en lugar de Cadena final estática para evitar tener todos esos bytes innecesarios cargados en la memoria. ¡En teléfonos móviles, quieres guardar toda la memoria posible!

-1

Parece que está pasando todas sus sentencias SQL en una cadena. Eso es un problema porque execSQL espera "una sola declaración que no sea una consulta" (ver documentación [aquí] [1]). Lo que sigue es una solución algo fea pero que funciona.

tengo todas mis instrucciones SQL en un archivo de la siguiente manera:

INSERT INTO tabla1 VALORES (1, 2, 3);

INSERT INTO table1 VALUES (4, 5, 6);

INSERT INTO table1 VALUES (7, 8, 9);

Aviso las nuevas líneas en entre el texto (punto y coma seguido de 2 nuevas líneas) entonces, haga lo siguiente:

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} 

Mis columnas de datos contienen burbujas de texto con nuevas líneas y puntos y comas, por lo que tenía que encontrar un separador de comando diferente.Solo asegúrese de ser creativo con Split Str: use algo que sabe que no existe en sus datos.

HTH Gerardo

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

+0

que hacer una división (";") también, y mi problema no era sobre las declaraciones SQL, pero caracteres de codificación. – tbruyelle

1

estoy usando un enfoque diferente: En lugar de las cargas de ejecución de sentencias SQL (que se llevará mucho tiempo para completar), construyo mi base de datos sqlite en el escritorio, la coloco en la carpeta de activos, creo un db sqlite vacío en android y copio el db de la carpeta assets en la carpeta de la base de datos. Este es un gran aumento en la velocidad. Tenga en cuenta que primero necesita crear una base de datos vacía en Android, y luego puede copiarla y sobrescribirla. De lo contrario, Android no te permitirá escribir un archivo db en la carpeta de la base de datos. Hay varios ejemplos en internet. Por cierto, parece que este enfoque funciona mejor, si el archivo db no tiene extensión de archivo.

+0

¿puedes compartir el código que usaste? –

Cuestiones relacionadas