我正在尝试在我的应用中按需备份和恢复数据库。该代码确实创建了一个具有正确名称的Google云端硬盘文件,但是当我恢复它或在驱动器中查看时,我得到了#34;数据库磁盘映像格式错误"。
从我的研究中得到最好的"我可以找到的解释是在上传之前数据库没有关闭。
我在SQLiteHelper上调用close()
。
我缺少什么?
我犯了错误吗?
有不同的原因吗?我发现提前写入记录也可能导致这种情况。我禁用了WAL仍然有问题。如何在上传之前检查是否格式错误?
MySQLiteHelper db;
private DriveFile mfile;
private File getDbPath() {
return this.getDatabasePath(DATABASE_NAME);
}
private ResultCallback<ContentsResult> writeToFile = new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error opening file");
return;
}
db.close();
try {
FileInputStream is = new FileInputStream(getDbPath());
BufferedInputStream in = new BufferedInputStream(is);
byte[] buffer = new byte[8 * 1024];
Contents content = result.getContents();
BufferedOutputStream out = new BufferedOutputStream(content.getOutputStream());
int n = 0;
while( ( n = in.read(buffer) ) > 0 ) {
out.write(buffer, 0, n);
}
in.close();
mfile.commitAndCloseContents(mGoogleApiClient, content).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status result) {
showMessage("file done");
db = new MySQLiteHelper(context);
}
});
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
private void openNewFile (ContentsResult result) {
String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db");
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(DATABASE_NAME)
.setMimeType(mimeType)
.setPinned(true)
.setStarred(true).build();
Drive.DriveApi.getRootFolder(mGoogleApiClient) //getAppFolder
.createFile(mGoogleApiClient, changeSet, result.getContents())
.setResultCallback(new ResultCallback<DriveFileResult>() {
@Override
public void onResult(DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error while trying to create the file");
return;
}
mfile = result.getDriveFile();
mfile.openContents(mGoogleApiClient, DriveFile.MODE_WRITE_ONLY, null).setResultCallback(writeToFile);
}
});
}
public void backupDB(View v) {
db.close();
Drive.DriveApi.newContents(mGoogleApiClient).setResultCallback(new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error while trying to create new file contents");
return;
}
final ContentsResult res = result;
Query query = new Query.Builder().addFilter(Filters.eq(SearchableField.TITLE, DATABASE_NAME)).build();
//TODO change this to appfolder search eventually
Drive.DriveApi.query(mGoogleApiClient, query)
.setResultCallback(new ResultCallback<MetadataBufferResult>() {
@Override
public void onResult(MetadataBufferResult result) {
MetadataBuffer mdb = result.getMetadataBuffer();
if (mdb == null) {
openNewFile(res);
} else {
for (Metadata md : mdb) {
if (!md.isTrashed()) {
mfile = Drive.DriveApi.getFile(mGoogleApiClient, md.getDriveId());
mfile.openContents(mGoogleApiClient, DriveFile.MODE_WRITE_ONLY, null).setResultCallback(writeToFile);
return;
}
}
openNewFile(res);
}
}
});
}
});
}
private ResultCallback<ContentsResult> readFromFile = new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error opening file");
return;
}
try {
db.close();//close database to make sure no open connections
Contents content = result.getContents();
InputStream is = content.getInputStream();
BufferedInputStream in = new BufferedInputStream(is);
FileOutputStream fos = new FileOutputStream(getDbPath());
BufferedOutputStream out = new BufferedOutputStream(fos);
byte[] buffer = new byte[8 * 1024];
int n = 0;
while( ( n = in.read(buffer) ) > 0 ) {
out.write(buffer, 0, n);
}
in.close();
out.flush();
out.close();
mfile.commitAndCloseContents(mGoogleApiClient, content).setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status result) {
showMessage("file done");
db = new MySQLiteHelper(context);
}
});
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void restoreDB(View v) {
Drive.DriveApi.newContents(mGoogleApiClient).setResultCallback(new ResultCallback<ContentsResult>() {
@Override
public void onResult(ContentsResult result) {
if (!result.getStatus().isSuccess()) {
Log.v(TAG, "Error while trying to create new file contents");
return;
}
final ContentsResult res = result;
Query query = new Query.Builder().addFilter(Filters.eq(SearchableField.TITLE, DATABASE_NAME)).build();
//TODO change this to appfolder search eventually
Drive.DriveApi.query(mGoogleApiClient, query)
.setResultCallback(new ResultCallback<MetadataBufferResult>() {
@Override
public void onResult(MetadataBufferResult result) {
MetadataBuffer mdb = result.getMetadataBuffer();
if (mdb == null) {
showMessage("no file exists1");//TODO by string id
} else {
for (Metadata md : mdb) {
if (!md.isTrashed()) {
mfile = Drive.DriveApi.getFile(mGoogleApiClient, md.getDriveId());
mfile.openContents(mGoogleApiClient, DriveFile.MODE_READ_ONLY, null).setResultCallback(readFromFile);
showMessage("file done?");//TODO
return;
}
}
showMessage("no file exists2");//TODO by string id
}
}
});
}
});
}
答案 0 :(得分:0)
DriveFile mfile.commitAndCloseContents()
不计入out.flush()
的{{1}}和out.close()
。
你仍然必须冲洗并关闭。