Android从内部存储到外部存储的复制数据库

时间:2012-01-30 15:55:04

标签: android database

我正在尝试将现有数据库从内部存储复制到外部存储,但我遇到了一些问题。它说the file does not exist。以下是我实际使用的内容:

将文件从内部存储复制到外部存储:

    private void copyFile(String src, String dst) throws IOException{
    FileChannel inChannel = new FileInputStream(src).getChannel();
    FileChannel outChannel = new FileOutputStream(dst).getChannel();
    try
    {
        inChannel.transferTo(0, inChannel.size(), outChannel);
    }
    finally
    {
        if (inChannel != null)
            inChannel.close();
        if (outChannel != null)
            outChannel.close();
    }
}

我正在使用它:

copyFile("/data/data/com.example.test/databases/database.sqlite","/sdcard/.Example/Data/database.sqlite");

但它不起作用,我很确定内部存储中的数据库是否存在。

如果我在copyFile "/sdcard/.Example/Data/"中设置为目标文件夹,则会在Data中创建文件.Example

我缺少什么建议?

5 个答案:

答案 0 :(得分:6)

使用此选项将数据库复制到SD卡。

public void copyFile()
    {
        try 
        {
            File sd = Environment.getExternalStorageDirectory();
            File data = Environment.getDataDirectory();

            if (sd.canWrite()) 
            {
                String currentDBPath = "\\data\\your.package.name\\databases\\dabase_name";
                String backupDBPath = "database_name";
                File currentDB = new File(data, currentDBPath);
                File backupDB = new File(sd, backupDBPath);

                if (currentDB.exists()) {
                    FileChannel src = new FileInputStream(currentDB).getChannel();
                    FileChannel dst = new FileOutputStream(backupDB).getChannel();
                    dst.transferFrom(src, 0, src.size());
                    src.close();
                    dst.close();
                }
                if(bool == true)
                {
                    Toast.makeText(Settings.this, "Backup Complete", Toast.LENGTH_SHORT).show();
                    bool = false;
                }
            }               
        } 
        catch (Exception e) {
            Log.w("Settings Backup", e);
        }
    }

答案 1 :(得分:4)

如果你不知道你的应用程序路径,那么你可以使用它:

//for without "Resource leak: '<unassigned Closeable value>' is never closed" warning, something like this
public void copyAppDbToDownloadFolder() throws IOException {
    try {
        String currDate = Constants.APP_DATE_SHORT_FORMAT.format(new Date());
        File backupDB = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), DbContract.DATABASE_BUCKUP_NAME + currDate + ".db");
        File currentDB = appCon.getDatabasePath(DbContract.DATABASE_NAME);
        if (currentDB.exists()) {
            FileInputStream fis = new FileInputStream(currentDB);
            FileOutputStream fos = new FileOutputStream(backupDB);
            fos.getChannel().transferFrom(fis.getChannel(), 0, fis.getChannel().size());
            // or fis.getChannel().transferTo(0, fis.getChannel().size(), fos.getChannel());
            fis.close();
            fos.close();
            Log.i("Database successfully", " copied to download folder");
            return true;
        }
    } catch (IOException e) {
        Log.d("Copying Database", "fail, reason:", e);
    }
}

或者如果您需要将数据库复制到公共“下载”文件夹,那么您可以使用:

public void copyAppDbToDownloadFolder() throws IOException {
    try {
        File backupDB = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "toDatabaseName"); // for example "my_data_backup.db"
        File currentDB = getApplicationContext().getDatabasePath("databaseName"); //databaseName=your current application database name, for example "my_data.db"
        if (currentDB.exists()) {
            FileInputStream fis = new FileInputStream(currentDB);
            FileOutputStream fos = new FileOutputStream(backupDB);
            fos.getChannel().transferFrom(fis.getChannel(), 0, fis.getChannel().size());
            // or fis.getChannel().transferTo(0, fis.getChannel().size(), fos.getChannel());
            fis.close();
            fos.close();
            Log.i("Database successfully", " copied to download folder");
            return true;
        } else Log.i("Copying Database", " fail, database not found");
    } catch (IOException e) {
        Log.d("Copying Database", "fail, reason:", e);
    }
}

这在我的Nexus 4设备上完美运行。

答案 2 :(得分:0)

您是否添加了WRITE_EXTERNAL_STORAGE权限?

<?xml version="1.0" encoding="utf-8"?>
<manifest ...
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest> 

答案 3 :(得分:0)

此程序可以将名为“您的数据库名称”的数据库从Android应用程序的内部存储复制到外部存储。它创建一个名为“文件夹名称”的文件夹,然后将数据库复制到名为“备份数据库名称”的文件中那个文件夹

这个程序与android marshmallow兼容 2.使用MediaScannerConnection时,您可以立即从具有Windows操作系统的计算机复制备份文件,而无需重新启动系统。 3.如果“文件夹名称”不存在,它将自动创建
4.如果指定的备份文件名已存在,则会显示警告对话框

if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)== PackageManager.PERMISSION_DENIED){
    if(ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 5);
    }
    else{
        ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},5);
    }
}
else{
    final File backupDb=new File(Environment.getExternalStorageDirectory().getPath()+File.separator+"<Folder Name>"+File.separator+"<Backup Database Name>");
    final File currentDB = new File(String.valueOf(getApplicationContext().getDatabasePath("<Your Database Name>")));
    if(backupDb.exists()){
        AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this)
                .setTitle("Alert")
                .setMessage("File already exists.Do you want to replace it")
                .setCancelable(false)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if(!new File(Environment.getExternalStorageDirectory().getPath()+File.separator+"<Folder Name>").canWrite()) {
                            Toast.makeText(MainActivity.this, "Unable to write into external storage", Toast.LENGTH_SHORT).show();
                        }
                        else{
                            if(!currentDB.exists()){
                                Toast.makeText(MainActivity.this, "Database doesn't exists", Toast.LENGTH_SHORT).show();
                            }
                            else{
                                try {
                                    FileChannel src = new FileInputStream(currentDB).getChannel();
                                    FileChannel dst = new FileOutputStream(backupDb).getChannel();
                                    dst.transferFrom(src, 0, src.size());
                                    src.close();
                                    dst.close();
                                    MediaScannerConnection.scanFile(getApplicationContext(), new String[]{backupDb.toString()}, null, null);
                                    Toast.makeText(MainActivity.this, "Database successfully copied to external storage", Toast.LENGTH_SHORT).show();
                                    editText.setText(null);
                                }catch(Exception e){
                                    Toast.makeText(MainActivity.this, "Got exception" + e, Toast.LENGTH_SHORT).show();
                                }
                            }
                        }
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(MainActivity.this, "Please enter another name", Toast.LENGTH_SHORT).show();
                    }
                })
                .setIcon(R.drawable.alert);
        AlertDialog dialog = builder.create();
        dialog.show();
    }
    else{
        new File(Environment.getExternalStorageDirectory().getPath()+File.separator+"<Folder Name>").mkdir();
        if(!new File(Environment.getExternalStorageDirectory().getPath()+File.separator+"<Folder Name>").canWrite()) {
            Toast.makeText(MainActivity.this, "Unable to write into external storage", Toast.LENGTH_SHORT).show();
        }
        else{
            if(!currentDB.exists()){
                Toast.makeText(MainActivity.this, "Database doesn't exists", Toast.LENGTH_SHORT).show();
            }
            else{
                try {
                    FileChannel src = new FileInputStream(currentDB).getChannel();
                    FileChannel dst = new FileOutputStream(backupDb).getChannel();
                    dst.transferFrom(src, 0, src.size());
                    src.close();
                    dst.close();
                    MediaScannerConnection.scanFile(getApplicationContext(), new String[]{backupDb.toString()}, null, null);
                    editText.setText(null);
                    Toast.makeText(MainActivity.this, "Database successfully copied to external storage", Toast.LENGTH_SHORT).show();
                }catch(Exception e){
                    Toast.makeText(MainActivity.this, "Got exception" + e, Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}

“您的数据库名称” - &gt;应用程序内部的数据库
“备份数据库名称” - &gt;要在其中复制数据库的文件
“文件夹名称” - &gt;要存储备份数据库的文件夹

答案 4 :(得分:0)

我建议使用此方法:

public static boolean copyFile(String from, String to) {
    boolean result = false;
    try{
        File dir = new File(to.substring(0, to.lastIndexOf('/')));
        dir.mkdirs();
        File tof = new File(dir, to.substring(to.lastIndexOf('/') + 1));
        int byteread;
        File oldfile = new File(from);
        if(oldfile.exists()){
            InputStream inStream = new FileInputStream(from);
            FileOutputStream fs = new FileOutputStream(tof);
            byte[] buffer = new byte[1024];
            while((byteread = inStream.read(buffer)) != -1){
                fs.write(buffer, 0, byteread);
            }
            inStream.close();
            fs.close();
        }
        result = true;
    }catch (Exception e){
        Log.e("copyFile", "Error copying file: " + e.getMessage());
    }
    return result;
}

将以这种方式调用:知道您的应用程序包以及内部存储器中保存的文件或数据库的名称,指示要复制的文件的源和目标:

//Obtiene ruta de base de datos origen.
String pathDB = getDatabasePath(NOMBRE_DATABASE).toString();
//Copia base de datos a destino definido.
copyFile(pathDB, Environment.getExternalStorageDirectory().getPath() + "/Android/data/" + getPackageName() + "/" + <nombre archivo destino>);

不要忘记在您的WRITE_EXTERNAL_STORAGE中添加权限AndroidManifest.xml

<uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />

通过这种方法,您可以将文件或数据库复制到外部存储中:

introducir la descripción de la imagen aquí


*重要

必须在操作系统大于** WRITE_EXTERNAL_STORAGE **(隐式也为READ_EXTERNAL_STORAGE)的设备上使用** Android 6.0 **权限:

//Verifica permisos para Android 6.0+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){

     checkExternalStoragePermission();
}

使用此方法:

private void checkExternalStoragePermission() {
    int permissionCheck = ContextCompat.checkSelfPermission(
            this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        Log.i("Mensaje", "No se tiene permiso para leer.");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 225);
    } else {
        Log.i("Mensaje", "Se tiene permiso para leer!");
    }
}