When moving temporary files, try to copy if rename fails, and throw if that fails too (#1686)
Fixes #1243
This commit is contained in:
parent
6eca92ea97
commit
aaa904e075
2 changed files with 55 additions and 25 deletions
|
@ -4,11 +4,13 @@ package com.fsck.k9.helper;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.fsck.k9.K9;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
|
||||
public class FileHelper {
|
||||
|
@ -83,6 +85,50 @@ public class FileHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private static void copyFile(File from, File to) throws IOException {
|
||||
FileInputStream in = new FileInputStream(from);
|
||||
FileOutputStream out = new FileOutputStream(to);
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int count;
|
||||
while ((count = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
out.close();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(in);
|
||||
IOUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
public static void renameOrMoveByCopying(File from, File to) throws IOException {
|
||||
deleteFileIfExists(to);
|
||||
|
||||
boolean renameFailed = !from.renameTo(to);
|
||||
if (renameFailed) {
|
||||
copyFile(from, to);
|
||||
|
||||
boolean deleteFromFailed = !from.delete();
|
||||
if (deleteFromFailed) {
|
||||
Log.e(K9.LOG_TAG, "Unable to delete source file after copying to destination!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteFileIfExists(File to) throws IOException {
|
||||
boolean fileDoesNotExist = !to.exists();
|
||||
if (fileDoesNotExist) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean deleteOk = to.delete();
|
||||
if (deleteOk) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IOException("Unable to delete file: " + to.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static boolean move(final File from, final File to) {
|
||||
if (to.exists()) {
|
||||
if (!to.delete()) {
|
||||
|
@ -95,31 +141,17 @@ public class FileHelper {
|
|||
}
|
||||
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(from);
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(to);
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int count = -1;
|
||||
while ((count = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
} finally {
|
||||
try { in.close(); } catch (Throwable ignore) {}
|
||||
}
|
||||
copyFile(from, to);
|
||||
|
||||
if (!from.delete()) {
|
||||
Log.d(K9.LOG_TAG, "Unable to delete file: " + from.getAbsolutePath());
|
||||
boolean deleteFromFailed = !from.delete();
|
||||
if (deleteFromFailed) {
|
||||
Log.e(K9.LOG_TAG, "Unable to delete source file after copying to destination!");
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.w(K9.LOG_TAG, "cannot move " + from.getAbsolutePath() + " to " + to.getAbsolutePath(), e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void moveRecursive(final File fromDir, final File toDir) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import com.fsck.k9.Account;
|
|||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.activity.MessageReference;
|
||||
import com.fsck.k9.activity.Search;
|
||||
import com.fsck.k9.helper.FileHelper;
|
||||
import com.fsck.k9.helper.Utility;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Body;
|
||||
|
@ -1360,12 +1361,9 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
|||
return updateOrInsertMessagePart(db, cv, part, INVALID_MESSAGE_PART_ID);
|
||||
}
|
||||
|
||||
private void renameTemporaryFile(File file, String messagePartId) {
|
||||
File destination = localStore.getAttachmentFile(messagePartId);
|
||||
if (!file.renameTo(destination)) {
|
||||
Log.w(K9.LOG_TAG, "Couldn't rename temporary file " + file.getAbsolutePath() +
|
||||
" to " + destination.getAbsolutePath());
|
||||
}
|
||||
private void moveTemporaryFile(File tempFile, String messagePartId) throws IOException {
|
||||
File destinationFile = localStore.getAttachmentFile(messagePartId);
|
||||
FileHelper.renameOrMoveByCopying(tempFile, destinationFile);
|
||||
}
|
||||
|
||||
private long updateOrInsertMessagePart(SQLiteDatabase db, ContentValues cv, Part part, long existingMessagePartId)
|
||||
|
@ -1397,7 +1395,7 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
|||
}
|
||||
|
||||
if (file != null) {
|
||||
renameTemporaryFile(file, Long.toString(messagePartId));
|
||||
moveTemporaryFile(file, Long.toString(messagePartId));
|
||||
}
|
||||
|
||||
return messagePartId;
|
||||
|
|
Loading…
Reference in a new issue