Andy
Andy

Reputation: 135

Backing up SQLite database to external storage - Wrong file reference

I'm getting a ESDIR (is a directory) error from the exception catch. I know it's because of something wrong with the paths that I've used and it seems that I'm referencing a folder rather than a file (maybe?), but I'm unsure how to correct it.

I've checked that the .mkdirs is working - I can see the files get created.

Edit: With suggestions.

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

}

Error Log:

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

Following the feedback received I have altered the code so there are separate File variables for the directory path and the file path. I've also added in checks to ensure files/folders are there:

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

}

Then I get the following from the 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

So despite using the separate variable for the file path it still believes it is a directory?

Upvotes: 2

Views: 635

Answers (2)

JackTools.Net
JackTools.Net

Reputation: 734

The problem is that you have to create the directory without the filname and copy the file with the filename.

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

}

Upvotes: 1

Hamid Shatu
Hamid Shatu

Reputation: 9700

Update:

So, your LogCat error report saying that the following path isn't a file but a directory.

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

That's why when you are passing this path in the following line then its throwing java.io.FileNotFoundException error.

FileOutputStream outStream = new FileOutputStream(backupDBPath);

I think, now you get that where the problem is. So, you have to make sure that when you passing a path to FileOutputStream() constructor, then its a file not a directory.

The solution can be as...assume, you are trying to backup your Database in a Text.txt file then the your corrected code should be as follows....

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

This will solve your all problem.

Upvotes: 3

Related Questions