2011-06-30 11 views
41

Estoy tratando de implementar un simple SQLite exportación/importación con fines de copia de seguridad. Exportar es solo una cuestión de almacenar una copia del archivo raw current.db. Lo que quiero hacer para importar es simplemente eliminar el archivo antiguo current.db y cambiar el nombre del archivo imported.db al current.db. es posible? Cuando trato de esta solución, me sale el siguiente error:Exportación simple e importación de una base de datos SQLite en Android

06-30 13:33:38.831: ERROR/SQLiteOpenHelper(23570): 
    android.database.sqlite.SQLiteDatabaseCorruptException: error code 11: database disk image is malformed 

Si miro el archivo de base de datos en bruto en un navegador SQLite se ve bien.

Respuesta

101

Utilizo este código en el SQLiteOpenHelper en una de mis aplicaciones para importar un archivo de base de datos.

EDIT: Pegué mi método FileUtils.copyFile() en la pregunta.

SQLiteOpenHelper

public static String DB_FILEPATH = "/data/data/{package_name}/databases/database.db"; 

/** 
* Copies the database file at the specified location over the current 
* internal application database. 
* */ 
public boolean importDatabase(String dbPath) throws IOException { 

    // Close the SQLiteOpenHelper so it will commit the created empty 
    // database to internal storage. 
    close(); 
    File newDb = new File(dbPath); 
    File oldDb = new File(DB_FILEPATH); 
    if (newDb.exists()) { 
     FileUtils.copyFile(new FileInputStream(newDb), new FileOutputStream(oldDb)); 
     // Access the copied database so SQLiteHelper will cache it and mark 
     // it as created. 
     getWritableDatabase().close(); 
     return true; 
    } 
    return false; 
} 

FileUtils

public class FileUtils { 
    /** 
    * Creates the specified <code>toFile</code> as a byte for byte copy of the 
    * <code>fromFile</code>. If <code>toFile</code> already exists, then it 
    * will be replaced with a copy of <code>fromFile</code>. The name and path 
    * of <code>toFile</code> will be that of <code>toFile</code>.<br/> 
    * <br/> 
    * <i> Note: <code>fromFile</code> and <code>toFile</code> will be closed by 
    * this function.</i> 
    * 
    * @param fromFile 
    *   - FileInputStream for the file to copy from. 
    * @param toFile 
    *   - FileInputStream for the file to copy to. 
    */ 
    public static void copyFile(FileInputStream fromFile, FileOutputStream toFile) throws IOException { 
     FileChannel fromChannel = null; 
     FileChannel toChannel = null; 
     try { 
      fromChannel = fromFile.getChannel(); 
      toChannel = toFile.getChannel(); 
      fromChannel.transferTo(0, fromChannel.size(), toChannel); 
     } finally { 
      try { 
       if (fromChannel != null) { 
        fromChannel.close(); 
       } 
      } finally { 
       if (toChannel != null) { 
        toChannel.close(); 
       } 
      } 
     } 
    } 
} 

No se olvide de eliminar el archivo de base de datos anterior si es necesario.

+0

esto funcionó perfectamente gracias tanto! –

+0

esta es una solución muy buena. aclamaciones. –

+4

Recuerda votar las respuestas que te gusta, ayuda a la comunidad a saber cuáles son buenas y cuáles son basura. –

29

Este es un método simple para exportar la base de datos a una carpeta denominada carpeta de copia de seguridad puede que el nombre que desee y un método sencillo para importar la base de datos de la misma carpeta un

public class ExportImportDB extends Activity { 
     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      // TODO Auto-generated method stub 
      super.onCreate(savedInstanceState); 
//creating a new folder for the database to be backuped to 
      File direct = new File(Environment.getExternalStorageDirectory() + "/Exam Creator"); 

       if(!direct.exists()) 
       { 
        if(direct.mkdir()) 
         { 
         //directory is created; 
         } 

       } 
      exportDB(); 
      importDB(); 

     } 
    //importing database 
     private void importDB() { 
      // TODO Auto-generated method stub 

      try { 
       File sd = Environment.getExternalStorageDirectory(); 
       File data = Environment.getDataDirectory(); 

       if (sd.canWrite()) { 
        String currentDBPath= "//data//" + "PackageName" 
          + "//databases//" + "DatabaseName"; 
        String backupDBPath = "/BackupFolder/DatabaseName"; 
        File backupDB= new File(data, currentDBPath); 
        File currentDB = new File(sd, backupDBPath); 

        FileChannel src = new FileInputStream(currentDB).getChannel(); 
        FileChannel dst = new FileOutputStream(backupDB).getChannel(); 
        dst.transferFrom(src, 0, src.size()); 
        src.close(); 
        dst.close(); 
        Toast.makeText(getBaseContext(), backupDB.toString(), 
          Toast.LENGTH_LONG).show(); 

       } 
      } catch (Exception e) { 

       Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG) 
         .show(); 

      } 
     } 
    //exporting database 
     private void exportDB() { 
      // TODO Auto-generated method stub 

      try { 
       File sd = Environment.getExternalStorageDirectory(); 
       File data = Environment.getDataDirectory(); 

       if (sd.canWrite()) { 
        String currentDBPath= "//data//" + "PackageName" 
          + "//databases//" + "DatabaseName"; 
        String backupDBPath = "/BackupFolder/DatabaseName"; 
        File currentDB = new File(data, currentDBPath); 
        File backupDB = new File(sd, backupDBPath); 

        FileChannel src = new FileInputStream(currentDB).getChannel(); 
        FileChannel dst = new FileOutputStream(backupDB).getChannel(); 
        dst.transferFrom(src, 0, src.size()); 
        src.close(); 
        dst.close(); 
        Toast.makeText(getBaseContext(), backupDB.toString(), 
          Toast.LENGTH_LONG).show(); 

       } 
      } catch (Exception e) { 

       Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG) 
         .show(); 

      } 
     } 

    } 

No se olvide de añadir este permiso de proceder que

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > 
    </uses-permission> 

Disfruta

+1

de alguna manera los procedimientos importDB y exportDB son exactamente idénticos? – Taifun

+1

Incorrecto: si observa detenidamente, la variable 'currentDB' se refiere al archivo de la carpeta de datos en importDB y la carpeta sd en exportDB. – ravemir

+2

¿Funcionará eso en dispositivos no rooteados? – Sarfraz

Cuestiones relacionadas