删除文件夹后出现 AccessDeniedException
AccessDeniedException after folder deleted
I 运行 测试用例并将执行期间创建的文件保存在 'execution' 目录中(来自每个测试的文件在单独的子目录中)
在套件开始时我想清理这个文件夹
所以在 @BeforeSuite 方法中我读取了 'execution' 目录中的所有项目:
public static List<File> getRecursivelyAllFilesFromDirectory(String directory) throws IOException {
List<File> files = new ArrayList<>();
files.addAll(readAllFilesFromDirectory(directory));
List<File> subDirs = readSubdirectories(directory);
subDirs.forEach(dir -> {
try {
files.addAll(readAllFilesFromDirectory(dir.getPath()));
files.add(dir);
} catch (IOException e) {
e.printStackTrace();
}
});
return files;
}
然后我想删除所有内容
public static void cleanExecutionDirectory() throws IOException {
LOGGER.info("Cleaning execution directory...");
String executionDir = getExecutionDir();
List<File> files = FileUtils.getRecursivelyAllFilesFromDirectory(executionDir);
for (File file : files) {
file.delete();
}
LOGGER.info(String.format("%d items deleted", files.size()));
}
但接下来在 @BeforeScenario 中,我尝试为新执行创建具有相同名称的子文件夹
public static void setTestCaseDir(String testCaseName) throws IOException {
testCaseDir = testCaseName.split(StringUtils.SPACE)[0];
String executionDir = getExecutionDir();
Path testCaseDirPath = Paths.get(executionDir, testCaseDir);
boolean isSubDir = readSubdirectories(executionDir)
.stream()
.filter(subDir -> subDir.getPath().equals(testCaseDirPath))
.findFirst()
.isPresent();
if (!isSubDir) {
Files.createDirectory(testCaseDirPath);
}
testCaseDir = testCaseDirPath.toString();
}
我收到一个异常:
java.nio.file.AccessDeniedException: D:\...\src\test\resources\execution\TC01
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:504)
at java.nio.file.Files.createDirectory(Files.java:674)
at utils.ExecutionUtils.setTestCaseDir(ExecutionUtils.java:56)
at integration.steps.StepDefs.beforeScenario(StepDefs.java:29)
尽管 setTestCaseDir 方法中的 readSubdirectories() returns 空列表也会发生。
我在文件资源管理器中看到这个子目录是可见的,但我也无法访问它们。
当此执行由于此异常而失败时,此子文件夹将解锁并消失。
什么进程可能锁定了这个子文件夹以及如何解决这个问题?
请注意,对层次结构中文件的任何延迟未关闭操作都会阻止删除工作 - 因此请检查在这些目录上工作的其他测试并为目录流添加 try-with-resources (Files
list / newDirectoryStream) 和 File
Input/Output 流(还有 Windows 上的 MappedByteBuffer
)。
一旦修复,FileVisitor
和 Files.walkFileTree
提供了一种更可靠的删除树的方法,它比大型目录树上的递归 File.list
更快:
public static void main(String[] args) throws IOException {
var paths = Arrays.stream(args).map(Path::of).collect(Collectors.toList());
FileVisitor<Path> deleteTree = new FileVisitor<>() {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("Delete FILE "+file);
Files.delete(file);
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw exc;
}
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
System.out.println("Delete DIR "+dir);
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
};
for (Path p : paths) {
Files.walkFileTree(p, deleteTree);
}
}
受@DuncG 的启发,我使用 NIO2 和 Java8
解决了这个问题
public static void cleanExecutionDirectory() throws IOException {
LOGGER.info("Cleaning execution directory...");
File executionDir = new File(getExecutionDir());
if (executionDir.exists()) {
Path executionDirPath = Paths.get(getExecutionDir());
Files.walk(executionDirPath)
.sorted(Comparator.reverseOrder())
.forEach(path -> {
try {
Files.delete(path);
} catch (IOException e) {
e.printStackTrace();
}
});
LOGGER.info(String.format("Items deleted"));
}
executionDir.mkdir();
}
I 运行 测试用例并将执行期间创建的文件保存在 'execution' 目录中(来自每个测试的文件在单独的子目录中) 在套件开始时我想清理这个文件夹
所以在 @BeforeSuite 方法中我读取了 'execution' 目录中的所有项目:
public static List<File> getRecursivelyAllFilesFromDirectory(String directory) throws IOException {
List<File> files = new ArrayList<>();
files.addAll(readAllFilesFromDirectory(directory));
List<File> subDirs = readSubdirectories(directory);
subDirs.forEach(dir -> {
try {
files.addAll(readAllFilesFromDirectory(dir.getPath()));
files.add(dir);
} catch (IOException e) {
e.printStackTrace();
}
});
return files;
}
然后我想删除所有内容
public static void cleanExecutionDirectory() throws IOException {
LOGGER.info("Cleaning execution directory...");
String executionDir = getExecutionDir();
List<File> files = FileUtils.getRecursivelyAllFilesFromDirectory(executionDir);
for (File file : files) {
file.delete();
}
LOGGER.info(String.format("%d items deleted", files.size()));
}
但接下来在 @BeforeScenario 中,我尝试为新执行创建具有相同名称的子文件夹
public static void setTestCaseDir(String testCaseName) throws IOException {
testCaseDir = testCaseName.split(StringUtils.SPACE)[0];
String executionDir = getExecutionDir();
Path testCaseDirPath = Paths.get(executionDir, testCaseDir);
boolean isSubDir = readSubdirectories(executionDir)
.stream()
.filter(subDir -> subDir.getPath().equals(testCaseDirPath))
.findFirst()
.isPresent();
if (!isSubDir) {
Files.createDirectory(testCaseDirPath);
}
testCaseDir = testCaseDirPath.toString();
}
我收到一个异常:
java.nio.file.AccessDeniedException: D:\...\src\test\resources\execution\TC01
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.createDirectory(WindowsFileSystemProvider.java:504)
at java.nio.file.Files.createDirectory(Files.java:674)
at utils.ExecutionUtils.setTestCaseDir(ExecutionUtils.java:56)
at integration.steps.StepDefs.beforeScenario(StepDefs.java:29)
尽管 setTestCaseDir 方法中的 readSubdirectories() returns 空列表也会发生。 我在文件资源管理器中看到这个子目录是可见的,但我也无法访问它们。 当此执行由于此异常而失败时,此子文件夹将解锁并消失。
什么进程可能锁定了这个子文件夹以及如何解决这个问题?
请注意,对层次结构中文件的任何延迟未关闭操作都会阻止删除工作 - 因此请检查在这些目录上工作的其他测试并为目录流添加 try-with-resources (Files
list / newDirectoryStream) 和 File
Input/Output 流(还有 Windows 上的 MappedByteBuffer
)。
一旦修复,FileVisitor
和 Files.walkFileTree
提供了一种更可靠的删除树的方法,它比大型目录树上的递归 File.list
更快:
public static void main(String[] args) throws IOException {
var paths = Arrays.stream(args).map(Path::of).collect(Collectors.toList());
FileVisitor<Path> deleteTree = new FileVisitor<>() {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println("Delete FILE "+file);
Files.delete(file);
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw exc;
}
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
System.out.println("Delete DIR "+dir);
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
};
for (Path p : paths) {
Files.walkFileTree(p, deleteTree);
}
}
受@DuncG 的启发,我使用 NIO2 和 Java8
解决了这个问题public static void cleanExecutionDirectory() throws IOException {
LOGGER.info("Cleaning execution directory...");
File executionDir = new File(getExecutionDir());
if (executionDir.exists()) {
Path executionDirPath = Paths.get(getExecutionDir());
Files.walk(executionDirPath)
.sorted(Comparator.reverseOrder())
.forEach(path -> {
try {
Files.delete(path);
} catch (IOException e) {
e.printStackTrace();
}
});
LOGGER.info(String.format("Items deleted"));
}
executionDir.mkdir();
}