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

Java 将SQLite数据库备份到外部存储-文件引用错误,java,android,sqlite,Java,Android,Sqlite,我得到一个ESDIR是异常捕获中的目录错误。我知道这是因为我使用的路径有问题,似乎我引用的是一个文件夹而不是一个文件,但我不确定如何更正它 我已经检查了.mkdirs是否正常工作-我可以看到创建的文件 编辑:有建议 private void exportDB(){ try { String DB =getDatabasePath(DBHandler.DATABASE_NAME).toString(); Toast.makeText(getAp

我得到一个ESDIR是异常捕获中的目录错误。我知道这是因为我使用的路径有问题,似乎我引用的是一个文件夹而不是一个文件,但我不确定如何更正它

我已经检查了.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
然后我从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
因此,尽管对文件路径使用了单独的变量,它仍然认为它是一个目录?

更新:

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

/storage/emulated/0/com.AH.memorisethai/Backup/database.db
这就是为什么当您在下一行中传递此路径时,它会抛出java.io.FileNotFoundException错误

我想,现在你明白问题所在了。因此,您必须确保在向FileOutputStream构造函数传递路径时,它是一个文件而不是目录

/storage/emulated/0/com.AH.memorisethai/Backup/database.db
解决方案可以是…假设,您试图在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);
这将解决您的所有问题。

更新:

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

/storage/emulated/0/com.AH.memorisethai/Backup/database.db
这就是为什么当您在下一行中传递此路径时,它会抛出java.io.FileNotFoundException错误

我想,现在你明白问题所在了。因此,您必须确保在向FileOutputStream构造函数传递路径时,它是一个文件而不是目录

/storage/emulated/0/com.AH.memorisethai/Backup/database.db
解决方案可以是…假设,您试图在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);

这将解决您的所有问题。

问题是,您必须创建不带文件名的目录,并用文件名复制文件

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

}

问题是,您必须创建不带文件名的目录,然后用文件名复制文件

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

}

备份数据库路径中的文件名在哪里?我已将/database.db添加到备份数据库路径的末尾,但仍然存在相同的问题错误更改为file not found exception备份数据库路径中的文件名在哪里?我已将/database.db添加到备份数据库路径的末尾,但仍然存在相同的问题错误更改为file not found Exception我编辑了代码,以便getExternalStorageDirectory在保存为SD之前进入字符串,但我得到了相同的结果。然后,您应该发布LogCat错误报告。没有这些,很难说什么。对不起,我不知道如何过滤LogCat报告以显示任何有意义的内容。这里似乎没有出现错误,因为它显示在exception.catch exception e{e.printStackTrace;}中,就像这里的e.printStackTrace;将错误详细信息打印到您的catch块中。然后从LogCat复制错误日志并粘贴到这里。谢谢,我成功地注销了日志。请参阅更新的帖子了解详细信息。我已经编辑了代码,以便getExternalStorageDirectory在保存为SD之前转到字符串,但我得到了相同的结果。然后您应该发布LogCat错误报告。没有这些,很难说什么。对不起,我不知道如何过滤LogCat报告以显示任何有意义的内容。这里似乎没有出现错误,因为它显示在exception.catch exception e{e.printStackTrace;}中,就像这里的e.printStackTrace;将错误详细信息打印到您的catch块中。然后从LogCat复制错误日志并粘贴到这里。谢谢,我成功地注销了日志。详情请参阅更新的帖子更新我的答案。我忘了在路径外创建文件。更新了我的答案。我忘了在路径外创建一个文件。