2014-10-12 58 views
1

我有一个JavaFX应用程序,它显示来自VBox中某个文件夹的所有图像。垂直框中,建这样的:在JavaFX中安全关闭/删除ImageView的文件

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()方法没有抛出异常?

+0

我不能重现。我没有真正购买你的解释:没有创建后台线程来从'VBox'中删除'ImageView',并且一旦读取图像数据就应该释放文件句柄。你可以创建一个[MCVE](http://stackoverflow.com/help/mcve)吗? – 2014-10-12 19:43:01

+0

图像中显示的文件是唯一没有删除的文件,那是什么让我认为图像浏览不会释放图像资源。我会在本周的某个时候写一个MVCE。我还注意到,这个问题只发生在Windows 7上,而不是在win8或Linux上(全部使用Oracle Java SE 8)。 – 2014-10-13 20:05:08

+0

好的,我在Mac上,所以也许这就是为什么我不能重现它。有趣。 – 2014-10-13 20:26:41

回答

0

我知道这是一个真正的老问题,但我认为任何人都可以有同样的问题,我有它几天前。

当您创建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(),将调用垃圾收集器,他将释放内存之后,你现在可以删除文件。

享受,

对不起实物英语不好

+0

感谢您的回复,这是一个有趣的解决问题的方式,但对我来说看起来有点冒失。我通过将所有图像复制到临时文件夹,然后从该临时文件夹中读取图像文件解决了该问题。然后,我在应用程序关闭时以及每次启动应用程序时删除所有临时文件夹。这个解决方案似乎可以在所有操作系统上完美运行 – 2015-08-22 14:58:30