2011-06-30 16 views
41

Próbuję zaimplementować prosty eksport/import SQLite do celów kopii zapasowych. Eksport jest tylko kwestią przechowywania kopii surowego pliku current.db. Co chcę zrobić dla importu to po prostu usunąć stary plik current.db i zmienić nazwę pliku imported.db na current.db. czy to możliwe? Kiedy próbuję to rozwiązanie, pojawia się następujący błąd:Prosty eksport i import bazy danych SQLite na Androida

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

Jeśli patrzę na plik bazy surowca w SQLite przeglądarce wygląda dobrze.

Odpowiedz

101

Używam tego kodu w SQLiteOpenHelper w jednej z moich aplikacji do importowania pliku bazy danych.

EDYCJA: Wkleiłem moją metodę FileUtils.copyFile() do pytania.

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

Nie zapomnij usunąć stary plik bazy danych, jeśli jest to konieczne.

+0

to działało idealnie dziękuję bardzo! –

+0

to bardzo dobre rozwiązanie. Twoje zdrowie. –

+4

Pamiętaj, aby odpowiedzieć w górę na głosy, które lubisz, pomaga społeczności wiedzieć, które z nich są dobre, a które są śmieciami. –

29

Jest to prosta metoda, aby wyeksportować bazę danych do folderu o nazwie Folder kopii zapasowej można nazwać jak chcesz i prosty sposób zaimportować bazę danych z tego samego folderu

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(); 

      } 
     } 

    } 

nie zapomnij dodać to uprawnienie, aby kontynuować to

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

Ciesz

+1

w jakiś sposób procedury importDB i exportDB są dokładnie identyczne? – Taifun

+1

Nieprawidłowe: jeśli przyjrzeć ci się bliżej, zmienna 'currentDB' odwołuje się do pliku folderu danych w importDB, a folderu sd w exportDB. – ravemir

+2

Czy to działa na urządzeniu nierootowanym? – Sarfraz