2014-10-12 61 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