Browse Source

FileUtils: improve delete (Windows)

Ensure files are writable before trying to delete them.

Bug: 408846
Change-Id: I930a547594bba853c33634ae54bd64d236afade3
Signed-off-by: Alexander Nittka <alex@nittka.de>
tags/v5.8.0.202005061305-m2
Alexander Nittka 4 years ago
parent
commit
bc4ed530a5

+ 37
- 0
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java View File

@@ -78,6 +78,15 @@ public class FileUtilsTest {
}
}

@Test
public void testDeleteReadOnlyFile() throws IOException {
File f = new File(trash, "f");
FileUtils.createNewFile(f);
assertTrue(f.setReadOnly());
FileUtils.delete(f);
assertFalse(f.exists());
}

@Test
public void testDeleteRecursive() throws IOException {
File f1 = new File(trash, "test/test/a");
@@ -338,6 +347,34 @@ public class FileUtilsTest {
assertFalse(e.exists());
}

@Test
public void testDeleteNonRecursiveTreeNotOk() throws IOException {
File t = new File(trash, "t");
FileUtils.mkdir(t);
File f = new File(t, "f");
FileUtils.createNewFile(f);
try {
FileUtils.delete(t, FileUtils.EMPTY_DIRECTORIES_ONLY);
fail("expected failure to delete f");
} catch (IOException e) {
assertTrue(e.getMessage().endsWith(t.getAbsolutePath()));
}
assertTrue(f.exists());
assertTrue(t.exists());
}

@Test
public void testDeleteNonRecursiveTreeIgnoreError() throws IOException {
File t = new File(trash, "t");
FileUtils.mkdir(t);
File f = new File(t, "f");
FileUtils.createNewFile(f);
FileUtils.delete(t,
FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.IGNORE_ERRORS);
assertTrue(f.exists());
assertTrue(t.exists());
}

@Test
public void testRenameOverNonExistingFile() throws IOException {
File d = new File(trash, "d");

+ 33
- 18
org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java View File

@@ -20,6 +20,7 @@ import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.LinkOption;
@@ -180,21 +181,31 @@ public class FileUtils {
}

if (delete) {
Throwable t = null;
IOException t = null;
Path p = f.toPath();
try {
Files.delete(p);
return;
} catch (FileNotFoundException e) {
if ((options & (SKIP_MISSING | IGNORE_ERRORS)) == 0) {
throw new IOException(MessageFormat.format(
JGitText.get().deleteFileFailed,
f.getAbsolutePath()), e);
boolean tryAgain;
do {
tryAgain = false;
try {
Files.delete(p);
return;
} catch (NoSuchFileException | FileNotFoundException e) {
handleDeleteException(f, e, options,
SKIP_MISSING | IGNORE_ERRORS);
return;
} catch (DirectoryNotEmptyException e) {
handleDeleteException(f, e, options, IGNORE_ERRORS);
return;
} catch (IOException e) {
if (!f.canWrite()) {
tryAgain = f.setWritable(true);
}
if (!tryAgain) {
t = e;
}
}
return;
} catch (IOException e) {
t = e;
}
} while (tryAgain);

if ((options & RETRY) != 0) {
for (int i = 1; i < 10; i++) {
try {
@@ -210,11 +221,15 @@ public class FileUtils {
}
}
}
if ((options & IGNORE_ERRORS) == 0) {
throw new IOException(MessageFormat.format(
JGitText.get().deleteFileFailed, f.getAbsolutePath()),
t);
}
handleDeleteException(f, t, options, IGNORE_ERRORS);
}
}

private static void handleDeleteException(File f, IOException e,
int allOptions, int checkOptions) throws IOException {
if (e != null && (allOptions & checkOptions) == 0) {
throw new IOException(MessageFormat.format(
JGitText.get().deleteFileFailed, f.getAbsolutePath()), e);
}
}


Loading…
Cancel
Save