在Android上简单导出和导入SQLite数据库

时间:2011-06-30 20:45:00

标签: java android database sqlite

我正在尝试实施简单的SQLite导出/导入以进行备份。导出只是存储原始current.db文件的副本。我想要导入的内容是删除旧的current.db文件,并将imported.db文件重命名为current.db。这可能吗?当我尝试这个解决方案时,我收到以下错误:

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

如果我在SQLite浏览器中查看原始数据库文件,它看起来很好。

5 个答案:

答案 0 :(得分:110)

我在我的一个应用程序的SQLiteOpenHelper中使用此代码来导入数据库文件。

编辑:我将FileUtils.copyFile()方法粘贴到问题中。

<强> 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;
}

<强>文件实用程序

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

如有必要,请不要忘记删除旧的数据库文件。

答案 1 :(得分:33)

这是一种将数据库导出到名为备份文件夹的文件夹的简单方法,您可以根据需要为其命名,以及从同一文件夹导入数据库的简单方法

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

            }
        }

    }

别忘了添加此权限以继续

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

享受

答案 2 :(得分:2)

要导出数据库,而是使用SQLITE或ROOM:

首先,在AndroidManifest.xml文件中添加此权限:

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

第二,我们开始对db函数进行编码:

private void exportDB() {
    try {
        File dbFile = new File(this.getDatabasePath(DATABASE_NAME).getAbsolutePath());
        FileInputStream fis = new FileInputStream(dbFile);

        String outFileName = DirectoryName + File.separator +
                DATABASE_NAME + ".db";

        // Open the empty db as the output stream
        OutputStream output = new FileOutputStream(outFileName);

        // Transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = fis.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
        // Close the streams
        output.flush();
        output.close();
        fis.close();


    } catch (IOException e) {
        Log.e("dbBackup:", e.getMessage());
    }
}

每天创建文件夹,文件夹名称为当前日期:

public void createBackup() {

    sharedPref = getSharedPreferences("dbBackUp", MODE_PRIVATE);
    editor = sharedPref.edit();

    String dt = sharedPref.getString("dt", new SimpleDateFormat("dd-MM-yy").format(new Date()));

    if (dt != new SimpleDateFormat("dd-MM-yy").format(new Date())) {
        editor.putString("dt", new SimpleDateFormat("dd-MM-yy").format(new Date()));

        editor.commit();
    }

    File folder = new File(Environment.getExternalStorageDirectory() + File.separator + "BackupDBs");
    boolean success = true;
    if (!folder.exists()) {
        success = folder.mkdirs();
    }
    if (success) {

        DirectoryName = folder.getPath() + File.separator + sharedPref.getString("dt", "");
        folder = new File(DirectoryName);
        if (!folder.exists()) {
            success = folder.mkdirs();
        }
        if (success) {
            exportDB();
        }
    } else {
        Toast.makeText(this, "Not create folder", Toast.LENGTH_SHORT).show();
    }

}

  

分配不带.db扩展名的DATABASE_NAME,其数据类型为字符串

答案 3 :(得分:0)

如果您想在Kotlin中使用。完美地工作

 private fun exportDbFile() {

    try {

        //Existing DB Path
        val DB_PATH = "/data/packagename/databases/mydb.db"
        val DATA_DIRECTORY = Environment.getDataDirectory()
        val INITIAL_DB_PATH = File(DATA_DIRECTORY, DB_PATH)

        //COPY DB PATH
        val EXTERNAL_DIRECTORY: File = Environment.getExternalStorageDirectory()
        val COPY_DB = "/mynewfolder/mydb.db"
        val COPY_DB_PATH = File(EXTERNAL_DIRECTORY, COPY_DB)

        File(COPY_DB_PATH.parent!!).mkdirs()
        val srcChannel = FileInputStream(INITIAL_DB_PATH).channel

        val dstChannel = FileOutputStream(COPY_DB_PATH).channel
        dstChannel.transferFrom(srcChannel,0,srcChannel.size())
        srcChannel.close()
        dstChannel.close()

    } catch (excep: Exception) {
        Toast.makeText(this,"ERROR IN COPY $excep",Toast.LENGTH_LONG).show()
        Log.e("FILECOPYERROR>>>>",excep.toString())
        excep.printStackTrace()
    }

}

答案 4 :(得分:0)

在Android上导入和导出SQLite数据库

这是我的功能,用于将数据库导出到设备存储中

private void exportDB(){
    String DatabaseName = "Sycrypter.db";
    File sd = Environment.getExternalStorageDirectory();
    File data = Environment.getDataDirectory();
    FileChannel source=null;
    FileChannel destination=null;
    String currentDBPath = "/data/"+ "com.synnlabz.sycryptr" +"/databases/"+DatabaseName ;
    String backupDBPath = SAMPLE_DB_NAME;
    File currentDB = new File(data, currentDBPath);
    File backupDB = new File(sd, backupDBPath);
    try {
        source = new FileInputStream(currentDB).getChannel();
        destination = new FileOutputStream(backupDB).getChannel();
        destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();
        Toast.makeText(this, "Your Database is Exported !!", Toast.LENGTH_LONG).show();
    } catch(IOException e) {
        e.printStackTrace();
    }
}

这是我从设备存储导入数据库到Android应用程序的功能

private void importDB(){
    String dir=Environment.getExternalStorageDirectory().getAbsolutePath();
    File sd = new File(dir);
    File data = Environment.getDataDirectory();
    FileChannel source = null;
    FileChannel destination = null;
    String backupDBPath = "/data/com.synnlabz.sycryptr/databases/Sycrypter.db";
    String currentDBPath = "Sycrypter.db";
    File currentDB = new File(sd, currentDBPath);
    File backupDB = new File(data, backupDBPath);

    try {
        source = new FileInputStream(currentDB).getChannel();
        destination = new FileOutputStream(backupDB).getChannel();
        destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();
        Toast.makeText(this, "Your Database is Imported !!", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}