【发布时间】:2019-07-29 01:10:45
【问题描述】:
目前我正在使用流在我的应用程序中实现 SQlite 数据库备份功能。 当我备份数据库时它可以工作并且文件有数据,因为我已经通过“Db browser for SQlite”验证了它。但是,当尝试通过来自我的应用程序的数据库路径的 FilOuputStream 和通过 android SAF(存储访问框架)返回的 UrI 中的 InputStream 进行恢复时,指向我放置了数据库备份的外部存储,我得到损坏的数据库文件并且连接也关闭了。
以下是我为此目的使用的两种方法
备份
//back db to a URI
public synchronized static boolean backupDb(Context context, Uri uri, String dbNam) throws IOException {
File dbFile = new File(context.getDatabasePath(dbNam).getPath());
FileInputStream inFilStream = new FileInputStream(dbFile);
OutputStream outFilStream = context.getContentResolver().openOutputStream(uri);//new FileOutputStream(backupFile);
byte[] buffer = new byte[1024];
int length;
while ((length = inFilStream.read(buffer)) > 0) {
outFilStream.write(buffer, 0, length);
}
outFilStream.flush();
outFilStream.close();
inFilStream.close();
return true;
}
恢复备份
//restore db from a URI
public static synchronized boolean restoreBackup(Context context, Uri uri, String dbNam) {
try {
InputStream inFilStream = context.getContentResolver().openInputStream(uri);
File dbFile = new File(context.getDatabasePath(dbNam).getPath());
FileOutputStream outFilStream = new FileOutputStream(dbFile);
byte[] buffer = new byte[1024];
int length;
while ((length = inFilStream.read(buffer)) > 0) {
outFilStream.write(buffer, 0, length);
Log.wtf("db", "restoring backup up");
}
outFilStream.flush();
// using outFilStream.getFD().sync(); also not working
outFilStream.close();
inFilStream.close();
return true;
} catch (IOException e) {
return false;
}
}
日志
我不明白它为什么这样做,因为当我调试并将断点放在它工作的恢复方法中时,这很奇怪,请帮助找出那里出了什么问题。
【问题讨论】:
-
是
backupDb和restoreBackup中的输入文件和输出文件的大小相同。 (只是 File.length()) -
尝试复制并关闭应用程序。那么数据库是否有效?标头似乎是正确的,因为前 15 个字节是 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 根据Database File Format),所以可能是您遇到替换数据库和新数据库之间的冲突。或者,作为测试,恢复到不同的数据库名称,打开该数据库,看看你是否仍然遇到问题,如果没有,那么很确定替换和新的冲突(缓存数据)。
-
如果数据库使用 WAL,另一个问题可能是 -shm 和或 -wal 文件有数据。更多关于这个here.
标签: java file-io android-sqlite inputstream outputstream