I have a database and I want to copy it to SD Card to keep a backup and I found this code:
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();
}
}
As I wrote in the title I get the No such file or directory
ENOENT error when I try to do it.
Apparently the database should be stored right there. I've tried changing the path to a few different things but still nothing... I tried:
"/data/"+ "com.example.myapp" +"/"+"mydatabase.db"
and
"//data//"+ "com.example.myapp" +"//databases//"+"mydatabase"
Edit1: Also tried this and also doesn't work:
String currentDBPath = this.getDatabasePath("mydatabase").toString();
etc. nothing works and I also can't find a way to check the path in any way.
I basically have the database made, inserted a few rows into it and have some basic functions like add()
and delete()
etc. Am I missing something? I have no idea what else I can try.
Here's what logcat has to say about this:
01-18 11:34:46.215 10337-10337/com.example.myapp D/DBPATH: Database path is /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 (No such file or directory)
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: at 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)
As below the issue may not be with the database, rather it could be with the external storage and because the directories do not exist. The fix is to create the directories. Hopefully the following will work (did for me):-
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();
}
This may be of use Storage permission error in Marshmallow
Taking your code and adapting it as per (which checks the paths, see output) :-
java.io.FileNotFoundException: /mnt/sdcard/storage/extSdCard/mydatabase: open failed: ENOENT (No such file or directory)
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();
}
}
The ENOENT is not for the database but for the External storage as per :-
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