我已經使用zip存檔從應用程序實現了用戶數據備份,我將數據庫和共享首選項文件複製到zip存檔並計算輸入文件的MD5校驗和以防止用戶修改備份數據。ZipOutputStream在Android上生成損壞的zip文件
從存檔中恢復我將備份文件解壓縮到臨時目錄,檢查校驗和,然後將相關文件夾中的首選項\數據庫文件複製。
我的一些用戶抱怨應用程序生成損壞的備份文件(zip文件確實已損壞)。
這裏是代碼壓縮到壓縮文件中的所有文件:
public void backup(String filename) {
File file = new File(getBackupDirectory(), filename);
FileOutputStream fileOutputStream = null;
ZipOutputStream stream = null;
try {
String settingsMD5 = null;
String databaseMD5 = null;
if (file.exists())
file.delete();
fileOutputStream = new FileOutputStream(file);
stream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
File database = getDatabasePath(databaseFileName);
File dataDirectory = getFilesDir();
if (dataDirectory != null) {
File settings = new File(dataDirectory.getParentFile(), "/shared_prefs/" + PREFERENCES_FILENAME);
settingsMD5 = zipFile("preferences", stream, settings);
}
databaseMD5 = zipFile("database.db", stream, database);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(META_DATE, new SimpleDateFormat(DATE_FORMAT, Locale.US).format(new Date()));
jsonObject.put(META_DATABASE, databaseMD5);
jsonObject.put(META_SHARED_PREFS, settingsMD5);
} catch (Exception e) {
e.printStackTrace();
}
InputStream metadata = new ByteArrayInputStream(jsonObject.toString().getBytes("UTF-8"));
zipInputStream(stream, metadata, new ZipEntry("metadata"));
stream.finish();
stream.close();
stream = null;
return file;
} catch (FileNotFoundException e) {
//handling errrors
} catch (IOException e) {
//handling errrors
}
}
private String zipFile(String name, ZipOutputStream zipStream, File file) throws FileNotFoundException, IOException {
ZipEntry zipEntry = new ZipEntry(name);
return zipInputStream(zipStream, new FileInputStream(file), zipEntry);
}
private String zipInputStream(ZipOutputStream zipStream, InputStream fileInputStream, ZipEntry zipEntry) throws IOException {
InputStream inputStream = new BufferedInputStream(fileInputStream);
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
if (messageDigest != null)
inputStream = new DigestInputStream(inputStream, messageDigest);
} catch (NoSuchAlgorithmException e) {
}
zipStream.putNextEntry(zipEntry);
inputToOutput(inputStream, zipStream);
zipStream.closeEntry();
inputStream.close();
if (messageDigest != null) {
return getDigestString(messageDigest.digest());
}
return null;
}
private String getDigestString(byte[] digest) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
String hex = Integer.toHexString(0xFF & digest[i]);
if (hex.length() == 1) {
hex = new StringBuilder("0").append(hex).toString();
}
hexString.append(hex);
}
return hexString.toString();
}
private void inputToOutput(InputStream inputStream, OutputStream outputStream) throws IOException {
byte[] buffer = new byte[BUFFER];
int count = 0;
while ((count = inputStream.read(buffer, 0, BUFFER)) != -1) {
outputStream.write(buffer, 0, count);
}
}
我想你應該叫'stream.flush();關閉流之前'。 – SubOptimal 2014-10-21 06:39:22
我已添加stream.flush(); stream.finish()之後 - 有時仍然收到損壞的zip文件。 – nemezis 2014-10-21 06:42:05
是否有可能成爲這種損壞的zip文件的例子? – SubOptimal 2014-10-21 09:44:11