将SQLite数据库备份到外部存储 - 错误的文件引用

时间:2014-02-18 16:56:23

标签: java android sqlite

我从异常捕获中收到ESDIR (is a directory)错误。我知道这是因为我使用过的路径出了问题,似乎我引用的是文件夹而不是文件(可能?),但我不确定如何纠正它。

我已检查.mkdirs是否正常工作 - 我可以看到文件已创建。

编辑:有建议。

private void exportDB(){

      try {
          String DB =getDatabasePath(DBHandler.DATABASE_NAME).toString();
          Toast.makeText(getApplicationContext(), "Path is: " +DB, Toast.LENGTH_LONG).show();

          String sd = Environment.getExternalStorageDirectory().toString();
          Toast.makeText(getApplicationContext(), "Path is: " +sd, Toast.LENGTH_LONG).show();

              String backupDBPath = sd + "/com.AH.memorisethai/Backup/database.db";
              File currentDB =(getDatabasePath(DBHandler.DATABASE_NAME));
              File backupDB = new File(backupDBPath);
              backupDB.mkdirs();

              Toast.makeText(getApplicationContext(), "Path is: "+backupDBPath, Toast.LENGTH_LONG).show();

              FileInputStream inStream = new FileInputStream(currentDB);
              FileOutputStream outStream = new FileOutputStream(backupDBPath);
              FileChannel inChannel = inStream.getChannel();
              FileChannel outChannel = outStream.getChannel();
              inChannel.transferTo(0, inChannel.size(), outChannel);
              inStream.close();
              outStream.close();

      } catch (Exception e) {

          Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
      }

}

错误日志:

02-19 09:45:59.820: W/myApp(22243): Start Copy
02-19 09:45:59.825: W/System.err(22243): java.io.FileNotFoundException: /storage/emulated/0/com.AH.memorisethai/Backup/database.db: open failed: EISDIR (Is a directory)
02-19 09:45:59.825: W/System.err(22243):    at libcore.io.IoBridge.open(IoBridge.java:409)
02-19 09:45:59.825: W/System.err(22243):    at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
02-19 09:45:59.825: W/System.err(22243):    at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
02-19 09:45:59.830: W/System.err(22243):    at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
02-19 09:45:59.830: W/System.err(22243):    at com.AH.memorisethai.MainMenu.exportDB(MainMenu.java:44)
02-19 09:45:59.830: W/System.err(22243):    at com.AH.memorisethai.MainMenu.onCreate(MainMenu.java:23)
02-19 09:45:59.830: W/System.err(22243):    at android.app.Activity.performCreate(Activity.java:5372)
02-19 09:45:59.830: W/System.err(22243):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
02-19 09:45:59.830: W/System.err(22243):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
02-19 09:45:59.830: W/System.err(22243):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
02-19 09:45:59.830: W/System.err(22243):    at android.app.ActivityThread.access$700(ActivityThread.java:159)
02-19 09:45:59.830: W/System.err(22243):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
02-19 09:45:59.830: W/System.err(22243):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-19 09:45:59.830: W/System.err(22243):    at android.os.Looper.loop(Looper.java:176)
02-19 09:45:59.830: W/System.err(22243):    at android.app.ActivityThread.main(ActivityThread.java:5419)
02-19 09:45:59.830: W/System.err(22243):    at java.lang.reflect.Method.invokeNative(Native Method)
02-19 09:45:59.830: W/System.err(22243):    at java.lang.reflect.Method.invoke(Method.java:525)
02-19 09:45:59.830: W/System.err(22243):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
02-19 09:45:59.830: W/System.err(22243):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
02-19 09:45:59.830: W/System.err(22243):    at dalvik.system.NativeStart.main(Native Method)
02-19 09:45:59.830: W/System.err(22243): Caused by: libcore.io.ErrnoException: open failed: EISDIR (Is a directory)
02-19 09:45:59.830: W/System.err(22243):    at libcore.io.Posix.open(Native Method)
02-19 09:45:59.830: W/System.err(22243):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
02-19 09:45:59.830: W/System.err(22243):    at libcore.io.IoBridge.open(IoBridge.java:393)
02-19 09:45:59.835: W/System.err(22243):    ... 19 more

根据收到的反馈,我更改了代码,因此目录路径和文件路径有单独的File变量。我还添加了支票以确保文件/文件夹存在:

private void exportDB(){

      try {
          File DB =getDatabasePath(DBHandler.DATABASE_NAME);
          if (DB.isFile()){
              Toast.makeText(getApplicationContext(), "File isFile: " +DB, Toast.LENGTH_LONG).show();
              Log.w("myApp", "File:"+DB);
          } else if (DB.isDirectory()){
              Toast.makeText(getApplicationContext(), "Folder isDirectory: " +DB, Toast.LENGTH_LONG).show();
              Log.w("myApp", "Folder:"+DB);
          }

          File sd = Environment.getExternalStorageDirectory();
          Toast.makeText(getApplicationContext(), "Path is: " +sd, Toast.LENGTH_LONG).show();
          File backupDBFolder = new File(sd, "/com.AH.memorisethai/Backup/");
          File backupDBFile = new File(sd, "/com.AH.memorisethai/Backup/database.db");
          backupDBFolder.mkdirs();

          if (backupDBFolder.isDirectory()){
              Log.w("myApp","External folder isDirectory: "+backupDBFolder);
          } else{
              Log.w("myApp","Nothing found");
          }


           Log.w("myApp", "Start Copy");
           FileInputStream inStream = new FileInputStream(DB);
           FileOutputStream outStream = new FileOutputStream(backupDBFile);

           FileChannel inChannel = inStream.getChannel();
           FileChannel outChannel = outStream.getChannel();
           inChannel.transferTo(0, inChannel.size(), outChannel);
           inStream.close();
           outStream.close();
           Log.w("myApp", "End Copy");

      } catch (Exception e) {

          e.printStackTrace();
          //Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
      }

}

然后我从Logcat获得以下内容:

02-19 12:00:51.468: W/myApp(9243): File:/data/data/com.AH.memorisethai/databases/wordsmanager
02-19 12:00:51.483: W/myApp(9243): External folder isDirectory: /storage/emulated/0/com.AH.memorisethai/Backup
02-19 12:00:51.483: W/myApp(9243): Start Copy
02-19 12:00:51.483: W/System.err(9243): java.io.FileNotFoundException: /storage/emulated/0/com.AH.memorisethai/Backup/database.db: open failed: EISDIR (Is a directory)
02-19 12:00:51.488: W/System.err(9243):     at libcore.io.IoBridge.open(IoBridge.java:409)
02-19 12:00:51.488: W/System.err(9243):     at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
02-19 12:00:51.488: W/System.err(9243):     at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
02-19 12:00:51.488: W/System.err(9243):     at com.AH.memorisethai.MainMenu.exportDB(MainMenu.java:53)
02-19 12:00:51.488: W/System.err(9243):     at com.AH.memorisethai.MainMenu.onCreate(MainMenu.java:23)
02-19 12:00:51.488: W/System.err(9243):     at android.app.Activity.performCreate(Activity.java:5372)
02-19 12:00:51.488: W/System.err(9243):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
02-19 12:00:51.488: W/System.err(9243):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
02-19 12:00:51.488: W/System.err(9243):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
02-19 12:00:51.488: W/System.err(9243):     at android.app.ActivityThread.access$700(ActivityThread.java:159)
02-19 12:00:51.488: W/System.err(9243):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
02-19 12:00:51.488: W/System.err(9243):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-19 12:00:51.488: W/System.err(9243):     at android.os.Looper.loop(Looper.java:176)
02-19 12:00:51.488: W/System.err(9243):     at android.app.ActivityThread.main(ActivityThread.java:5419)
02-19 12:00:51.488: W/System.err(9243):     at java.lang.reflect.Method.invokeNative(Native Method)
02-19 12:00:51.488: W/System.err(9243):     at java.lang.reflect.Method.invoke(Method.java:525)
02-19 12:00:51.488: W/System.err(9243):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
02-19 12:00:51.488: W/System.err(9243):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
02-19 12:00:51.488: W/System.err(9243):     at dalvik.system.NativeStart.main(Native Method)
02-19 12:00:51.488: W/System.err(9243): Caused by: libcore.io.ErrnoException: open failed: EISDIR (Is a directory)
02-19 12:00:51.493: W/System.err(9243):     at libcore.io.Posix.open(Native Method)
02-19 12:00:51.493: W/System.err(9243):     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
02-19 12:00:51.493: W/System.err(9243):     at libcore.io.IoBridge.open(IoBridge.java:393)
02-19 12:00:51.493: W/System.err(9243):     ... 18 more

所以尽管对文件路径使用单独的变量,它仍然认为它是一个目录?

2 个答案:

答案 0 :(得分:3)

<强>更新

因此,您的LogCat错误报告指出以下路径不是文件而是目录。

/storage/emulated/0/com.AH.memorisethai/Backup/database.db

这就是为什么当您在以下行中传递此路径时,它会抛出java.io.FileNotFoundException错误。

FileOutputStream outStream = new FileOutputStream(backupDBPath);

我想,现在你可以解决问题所在。因此,您必须确保在将路径传递给FileOutputStream()构造函数时,其文件不是目录。

解决方案可以是......假设您尝试在Database文件中备份Text.txt,然后您的更正后的代码应如下所示....

String backupDBPath = sd + "/com.AH.memorisethai/Backup/database.db";
File backupDirectory = new File(backupDBPath);
backupDirectory.mkdirs();

String backupFilePath = backupDBPath + "/" + "Text.txt";
File backupFile = new File(backupFilePath);

FileOutputStream outStream = new FileOutputStream(backupFile);

这将解决您的所有问题。

答案 1 :(得分:1)

问题是您必须创建没有文件名的目录,并使用文件名复制文件。

private void exportDB(){

  try {
      String DB =getDatabasePath(DBHandler.DATABASE_NAME).toString();
      Toast.makeText(getApplicationContext(), "Path is: " +DB, Toast.LENGTH_LONG).show();

      String sd = Environment.getExternalStorageDirectory().toString();
      Toast.makeText(getApplicationContext(), "Path is: " +sd, Toast.LENGTH_LONG).show();

          String backupDBPath = sd + "/com.AH.memorisethai/Backup/";
          String backupDBFile = sd + "/com.AH.memorisethai/Backup/database.db";
          File currentDB =(getDatabasePath(DBHandler.DATABASE_NAME));
          File backupDB = new File(backupDBPath);
          File backupFile = new File(backupDBFile);
          backupDB.mkdirs();

          Toast.makeText(getApplicationContext(), "Path is: "+backupDBPath, Toast.LENGTH_LONG).show();

          FileInputStream inStream = new FileInputStream(currentDB);
          FileOutputStream outStream = new FileOutputStream(backupFile);
          FileChannel inChannel = inStream.getChannel();
          FileChannel outChannel = outStream.getChannel();
          inChannel.transferTo(0, inChannel.size(), outChannel);
          inStream.close();
          outStream.close();

  } catch (Exception e) {

      Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
  }

}