我正在尝试将现有数据库从内部存储复制到外部存储,但我遇到了一些问题。它说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
。
我缺少什么建议?
答案 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" />
通过这种方法,您可以将文件或数据库复制到外部存储中:
必须在操作系统大于** 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!");
}
}