如何将数据库从内部存储备份到外部(共享)存储

How to backup a database from internal storage to external(shared) storage

我的应用程序中有一个数据库。我想将其从我的应用程序内部存储备份或导出到外部(共享)存储。我有下面的代码来实现objective.

public void exportDB(){

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

    FileChannel source = null;
    FileChannel destination = null;

    File dbFile = context.getDatabasePath(SAMPLE_DB_NAME);

    String currentDBPath = dbFile.toString();
    String backupDBPath = SAMPLE_DB_NAME;

    File currentDB = new File(data, currentDBPath);
    File backupDB  = new File(sd, backupDBPath);

    if(sd.canWrite() &&  sd.canRead())
        Toast.makeText(context, "sd can read and write", Toast.LENGTH_LONG).show();
    else if(sd.canWrite() && !sd.canRead())
        Toast.makeText(context, "sd cannot read but write", Toast.LENGTH_LONG).show();
    else if(!sd.canWrite() && sd.canRead())
        Toast.makeText(context, "sd can read but not write", Toast.LENGTH_LONG).show();
    else
        Toast.makeText(context, "sd cannot read and write", Toast.LENGTH_LONG).show();


    try {
        source = new FileInputStream(currentDB).getChannel();
        destination = new FileOutputStream(backupDB).getChannel();
        destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();
        //Toast.makeText(this, "DB Exported!", Toast.LENGTH_LONG).show();
    } catch(IOException e) {
        e.printStackTrace();
    }
}

我已经在清单中添加了这两个权限

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

问题是我在 if else 语句中收到 sd 卡不可写且不可读的选项错误。

其次,我在日志中收到此错误。

10-07 11:58:25.388 18913-18913/com.free W/System.err: java.io.FileNotFoundException: /data/data/user/0/com.free/databases/database.db (No such file or directory)
10-07 11:58:25.390 18913-18913/com.free W/System.err:     at java.io.FileInputStream.open(Native Method)
10-07 11:58:25.392 18913-18913/com.free W/System.err:     at java.io.FileInputStream.<init>(FileInputStream.java:146)
10-07 11:58:25.394 18913-18913/com.free W/System.err:     at com.free.DatabaseManage.exportDB(DatabaseManage.java:56)
10-07 11:58:25.396 18913-18913/com.free W/System.err:     at com.free.MainActivity.onNavigationItemSelected(MainActivity.java:773)
10-07 11:58:25.398 18913-18913/com.free W/System.err:     at android.support.design.widget.NavigationView.onMenuItemSelected(NavigationView.java:156)
10-07 11:58:25.400 18913-18913/com.khan.free W/System.err:     at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
10-07 11:58:25.402 18913-18913/com.free W/System.err:     at android.support.v7.view.menu.SubMenuBuilder.dispatchMenuItemSelected(SubMenuBuilder.java:88)
10-07 11:58:25.403 18913-18913/com.free W/System.err:     at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:156)
10-07 11:58:25.405 18913-18913/com.free W/System.err:     at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:969)
10-07 11:58:25.407 18913-18913/com.free W/System.err:     at android.support.design.internal.NavigationMenuPresenter.onClick(NavigationMenuPresenter.java:342)
10-07 11:58:25.409 18913-18913/com.free W/System.err:     at android.view.View.performClick(View.java:6213)
10-07 11:58:25.411 18913-18913/com.free W/System.err:     at android.view.View$PerformClick.run(View.java:23645)
10-07 11:58:25.413 18913-18913/com.free W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
10-07 11:58:25.418 18913-18913/com.free W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
10-07 11:58:25.419 18913-18913/com.free W/System.err:     at android.os.Looper.loop(Looper.java:154)
10-07 11:58:25.420 18913-18913/com.free W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6692)
10-07 11:58:25.421 18913-18913/com.free W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
10-07 11:58:25.422 18913-18913/com.free W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
10-07 11:58:25.423 18913-18913/com.khan.free W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

我不知道哪里出错了。我该如何解决这个问题?

经过一些调试我找到了正确的答案。我正在发布正确答案。它可能会对某人有所帮助。

public void exportDB(){

    // it is the path to the existing database file in apps private storage
    final File dbFile = context.getDatabasePath(DATABASE_NAME);//existing database file path

    // this will give the devices internal storage as /storage/emulated/0
    File device = Environment.getExternalStorageDirectory();//device storage

    FileChannel source = null;
    FileChannel destination = null;

    try {
        source = new FileInputStream(dbFile).getChannel();
        destination = new FileOutputStream(device).getChannel();
        destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();

        Toast.makeText(this,"Database is exported to device storage",Toast.LENGTH_LONG).show();
    } catch(IOException e) {
        e.printStackTrace();
        Toast.makeText(this,"Failed to export database",Toast.LENGTH_LONG).show();
    }
}