我有一个数据库,我想将它复制到SD卡以进行备份,我发现了以下代码:

private void exportDB(){
    File sd = Environment.getExternalStorageDirectory();
    File data = Environment.getDataDirectory();
    FileChannel source=null;
    FileChannel destination=null;
    String currentDBPath = "/data/"+ "com.example.myapp" +"/databases/"+"mydatabase";
    String backupDBPath = "/storage/extSdCard/mydatabase";
    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();
    } catch(IOException e) {
        //e.printStackTrace();
        Toast.makeText(this, "Err:"+e, Toast.LENGTH_LONG).show();
    }
}

正如我在标题中所写的,当我尝试去做的时候,我得到了一个No such file or directory的错误。
显然数据库应该就在那里。
我试着改变一些不同的事情,但仍然没有…
我试过:
"/data/"+ "com.example.myapp" +"/"+"mydatabase.db"


"//data//"+ "com.example.myapp" +"//databases//"+"mydatabase"

Edit1:也尝试过但也不起作用:
String currentDBPath = this.getDatabasePath("mydatabase").toString();

等等,没什么用,我也找不到任何方法来检查路径。
我基本上已经建立了数据库,在其中插入了几行,并且有一些基本功能,比如add()delete()等等。我是否遗漏了什么?我不知道还能试什么。
下面是logcat要说的:
01-18 11:34:46.215 10337-10337/com.example.myapp d/db path:数据库路径为/data/data/com.example.myapp/databases/mydatabase.db
01-18 11:34:46.225 10337-10337/com.example.myapp w/system.err:java.io.filenotfoundexception:/data/data/com.example.myapp/databases/mydatabase.db:open failed:enoent(没有这样的文件或目录)
01-18 11:34:46.235 10337-10337/com.example.myapp w/system.err:at libcore.io.iobridge.open(iobridge.java:456)
01-18 11:34:46.235 10337-10337/com.example.myapp w/system.err:位于java.io.fileinputstream。(fileinputstream.java:76)
01-18 11:34:46.235 10337-10337/com.example.myapp w/system.err:at com.example.myapp.tabsactivity.exportdb(tabsactivity.java:183)
01-18 11:34:46.235 10337-10337/com.example.myapp w/system.err:at com.example.myapp.tabsactivity.onoptionsitemselected(tabsactivity.java:119)

最佳答案

如下所述,该问题可能与数据库无关,而是与外部存储有关,并且因为目录不存在。修复方法是创建目录。希望下面的方法对我有用:-

    try {
        source = new FileInputStream(currentDB).getChannel();
        (new File(backupDB.getParent())).mkdirs(); //<<<<<<<<<<<<<< ADDED
        destination = new FileOutputStream(backupDB).getChannel();
        //destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();
    } catch(IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "Err:"+e, Toast.LENGTH_LONG).show();
    }

为了测试,我已经评论了转移。P.S.转机正常。
也可能是权限问题(我的测试是在genymotion模拟器上进行的)。
刚刚在一个真实的设备上测试过,如果不授予权限,同样的错误也会发生。
刚刚在manifest和23以上版本的代码中测试了真正的设备设置权限。复制成功。:。-
java - 尝试在Android中复制SQLite数据库并获取“无此文件或目录”-LMLPHP
这可能有用Storage permission error in Marshmallow
获取代码并根据(检查路径,请参阅输出)调整代码:-
java.io.fileNotFoundException异常:
/mnt/sdcard/storage/extsdcard/mydatabase:打开失败:enoent(没有
文件或目录)
private void exportDB(){
    File sd = Environment.getExternalStorageDirectory();
    File data = Environment.getDataDirectory();
    FileChannel source=null;
    FileChannel destination=null;
    String currentDBPath = "/data/"+ getPackageName() +"/databases/"+DatabaseHandler.DATABASE_NAME;
    String retreivedDBPAth = getDatabasePath(DatabaseHandler.DATABASE_NAME).getPath();
    String backupDBPath = "/storage/extSdCard/mydatabase";
    File currentDB = new File(data, currentDBPath);
    File backupDB = new File(sd, backupDBPath);
    File retrievedDB = new File(retreivedDBPAth);
    Log.d("PATHS", " CurrentDB=" +
            currentDBPath + "\n\t" + currentDB.getPath() +
            "\n\tExists=" + String.valueOf(currentDB.exists()) +
            "\nBackup=" + backupDBPath + "\n\t" + backupDB.getPath() +
            "\n\tExists=" + String.valueOf(backupDB.exists()) +
            "\nRetrieved DB=" + retreivedDBPAth + "\n\t" + retrievedDB.getPath() +
            "\n\tExists=" + String.valueOf(retrievedDB.exists())
    );
    try {
        source = new FileInputStream(currentDB).getChannel();
        destination = new FileOutputStream(backupDB).getChannel();
        //destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();
    } catch(IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "Err:"+e, Toast.LENGTH_LONG).show();
    }
}

enoent不用于数据库,而是用于符合以下条件的外部存储:
01-18 11:11:32.017 2689-2689/? D/PATHS:  CurrentDB=/data/example.com.so48304909_spinner/databases/spinnerExample
                                            /data/data/example.com.so48304909_spinner/databases/spinnerExample
                                            Exists=true
                                        Backup=/storage/extSdCard/mydatabase
                                            /mnt/sdcard/storage/extSdCard/mydatabase
                                            Exists=false
                                        Retrieved DB=/data/data/example.com.so48304909_spinner/databases/spinnerExample
                                            /data/data/example.com.so48304909_spinner/databases/spinnerExample
                                            Exists=true
01-18 11:11:32.021 2689-2689/? W/System.err: java.io.FileNotFoundException: /mnt/sdcard/storage/extSdCard/mydatabase: open failed: ENOENT (No such file or directory)
01-18 11:11:32.021 2689-2689/? W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:416)
01-18 11:11:32.021 2689-2689/? W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
01-18 11:11:32.021 2689-2689/? W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
01-18 11:11:32.021 2689-2689/? W/System.err:     at example.com.so48304909_spinner.MainActivity.exportDB(MainActivity.java:162)
01-18 11:11:32.021 2689-2689/? W/System.err:     at example.com.so48304909_spinner.MainActivity.onCreate(MainActivity.java:38)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.Activity.performCreate(Activity.java:5008)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.ActivityThread.access$600(ActivityThread.java:130)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.os.Looper.loop(Looper.java:137)
01-18 11:11:32.021 2689-2689/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:4745)
01-18 11:11:32.021 2689-2689/? W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
01-18 11:11:32.021 2689-2689/? W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
01-18 11:11:32.021 2689-2689/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-18 11:11:32.021 2689-2689/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-18 11:11:32.021 2689-2689/? W/System.err:     at dalvik.system.NativeStart.main(Native Method)
01-18 11:11:32.021 2689-2689/? W/System.err: Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
01-18 11:11:32.021 2689-2689/? W/System.err:     at libcore.io.Posix.open(Native Method)
01-18 11:11:32.021 2689-2689/? W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
01-18 11:11:32.021 2689-2689/? W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:400)
01-18 11:11:32.021 2689-2689/? W/System.err:    ... 18 more

10-04 23:41