我正在使用jgit(版本
这是一个最小的独立示例,其唯一的依赖项是jgit 4.8.0.201706111038-r:
4.8.0.201706111038-r
)将git repo克隆到临时目录,并添加关闭挂钩以在终止后删除临时目录。但是,关机挂钩无法删除.git
子目录中的某些文件(尽管已经关闭了Git对象,这是jgit所需的)。有趣的是,如果我使用Path API (Files.delete(<PATH>)
)删除,删除只会失败一次,而不是使用旧的file.delete()
。这是一个最小的独立示例,其唯一的依赖项是jgit 4.8.0.201706111038-r:
public static void main(String... args) throws Exception {
String gitRepo = "https://github.com/netgloo/spring-boot-samples.git";
Path localDir = Files.createTempDirectory(null);
// Clone repo
Git git = Git.cloneRepository().setURI(gitRepo).setBranch("master").setDirectory(localDir.toFile()).call();
// Print some stuff to make sure that the git repo actually works
for (RevCommit c : git.log().call()) {
System.out.println(c);
}
git.getRepository().close(); // Close all the things!
git.close(); // Close all the things!
// Delete
Files.walkFileTree(localDir, new SimpleFileVisitor<Path>() {
void safeDelete(Path p) {
try {
Files.delete(p);
} catch (Exception e) {
try {
Files.delete(p);
} catch (Exception e2) {
System.err.println("Failed to delete " + p + " due to " + e.getClass().getSimpleName() + " using Files.detlete().\nTrying toFile().delete(): " + p.toFile().delete());
}
}
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
safeDelete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
safeDelete(dir);
return FileVisitResult.CONTINUE;
}
});
}
输出:
...
Failed to delete C:\Users\malt\AppData\Local\Temp\7908805853015958247\.git\objects\pack\pack-9cc3ec0769e34546bb7683f4e22ef67b3c800444.idx due to AccessDeniedException using Files.detlete().
Trying toFile().delete(): true
Failed to delete C:\Users\malt\AppData\Local\Temp\7908805853015958247\.git\objects\pack\pack-9cc3ec0769e34546bb7683f4e22ef67b3c800444.pack due to AccessDeniedException using Files.detlete().
Trying toFile().delete(): true
有人能解释一下为什么会发生这种情况吗?是否有办法让JGIT正确关闭这些文件,以便Files.delete()
可以正常工作?
close()
调用是多余的,我只是为了问题的目的而使调用非常明确。关于GC配置 - 我已经将您提供的代码添加到复制代码中,但我得到了相同的行为。然而,关于Files.delete()与File.delete()的解释似乎是正确的。 - Malt