2011-06-30 40 views
41

Ben yedekleme amacıyla basit bir SQLite ihracat/ithalat uygulamaya çalışıyorum. Dışa aktarma, yalnızca ham current.db dosyasının bir kopyasını depolamak meselesidir. İçe aktarmak için yapmak istediğim, eski current.db dosyasını silmektir ve imported.db dosyasını current.db olarak yeniden adlandırmaktır. Mümkün mü? Bir SQLite tarayıcıda ham veritabanı dosyasında bakarsakBasit bir ihracat ve ithalat bir SQLite veritabanı üzerinde Android

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

iyi görünüyor: Bu çözümü çalıştığınızda, aşağıdaki hatayı alıyorum.

cevap

101

Bir veritabanı dosyasını almak için bu kodu SQLiteOpenHelper numaralı uygulamalarda kullanıyorum.

DÜZENLEME: FileUtils.copyFile() yöntemimi soruya yapıştırdım.

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

gerekirse eski veritabanı dosyasını silmek unutmayın.

+0

Enjoy devam etmek için bu mükemmel çalıştı çok teşekkür ederim! –

+0

bu çok güzel bir çözümdür. şerefe. –

+4

Beğendiğiniz cevapları oylamayı unutmayın, topluluğun hangisinin iyi olduğunu ve önemsiz olduğunu bilmesine yardımcı olun. –

29

Bu

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

      } 
     } 

    } 

Dont eklemeyi unutmayın aynı klasörden veritabanını almak için istediğiniz kadar yedekleme klasörü bunun adı adında bir klasör ve basit yönteme veritabanını vermek basit bir yöntemdir Bu izin bu

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

+1

Bir şekilde importDB ve exportDB prosedürleri tam olarak aynı mı? – Taifun

+1

Yanlış: Eğer yakından bakarsanız, 'currentDB' değişkeni importDB'deki veri klasörü dosyasına ve exportDB'deki sd klasörüne geri döner. – ravemir

+2

Köklü olmayan cihazlarda çalışacak mı? – Sarfraz

İlgili konular