我有一个 JavaFX 应用程序,它显示 VBox 中某个文件夹中的所有图像。 VBox 的构建方式如下:
try (DirectoryStream<Path> stream = Files.newDirectoryStream(imagePath)) {
for (Path file : stream) {
String fileNameLc = file.toString().toLowerCase();
if (fileNameLc.matches(".*\\.(jpg|png)")) {
ImageView graph = new ImageView(new Image(Files.newInputStream(file)));
graph.setPreserveRatio(true);
imageVBox.getChildren().add(graph);
}
}
} catch (IOException ex) {
//
}
还有一个按钮可以删除 VBox 中显示的文件夹中的所有图像(以及所有其他文件)。这是按钮操作的代码:
imageVBox.getChildren().clear();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(imagePath)) {
for (Path file : stream) {
Files.delete(file);
System.out.println("Removing: " + file);
}
} catch (IOException ex) {
//
}
显示图像工作正常,但删除它们不起作用。在标准输出中我看到
Removing: /foo/img1.jpg
Removing: /foo/img2.jpg
...
没有抛出异常,但如果检查文件夹的内容,图像文件仍然存在。文件夹中所有非图像(且未在 VBox 中显示)的文件均已成功删除,但 VBox 中显示的图像并未成功删除。
我认为原因是之后
imageVBox.getChildren().clear();
后台线程开始删除图像,.clear() 方法立即返回。这样,删除文件的代码块就会在图像资源关闭之前执行。
关闭图像的最佳方式是什么?为什么 Files.delete() 方法没有抛出异常?
最佳答案
我知道这是一个非常老的问题,但我认为任何人都可能遇到同样的问题,我几天前就遇到了。
问题很简单,当你创建ImageView时,图像是由JAVA加载的,在释放内存之前你不能删除它。
我不知道为什么它们没有错误,但是如果您尝试删除,您会看到错误 在执行jar的过程中手动加载镜像文件。
要获得免费的 ImageView,你必须这样做:
Image graph = new Image(Files.newInputStream(file));
ImageView graphView = new ImageView(graph);
graph = null;
graphView.setImage(null);
System.gc();
不要忘记 System.gc(),它将调用垃圾收集器并释放内存,之后您现在可以删除该文件。
享受,
对不起,英语真的很糟糕
关于java - 在 JavaFX 中安全地关闭/删除 ImageView 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26325996/