2011-11-30 113 views
3

我有一個實現了一個偵聽器,通知我們是否在特定目錄中接收到新文件。這是通過輪詢和使用TimerTask來實現的。 現在程序已經設置好,一旦它接收到一個新文件,它就會調用另一個java程序來打開文件並驗證它是否是正確的文件。我的問題是,由於輪詢發生了指定的秒數,因此可能會出現文件被複制到該目錄中並因此被窗口鎖定的情況。如何在java中打開文件之前等待windows進程完成之前

由於嘗試打開它進行驗證的其他Java程序無法(「文件正被另一個進程使用」),所以會拋出IOException。

有什麼辦法可以知道Windows何時完成了複製,然後調用第二個程序從java中進行驗證?

如果有人需要它們以幫助,我將非常樂意發佈代碼片段。

感謝

+0

其他的java程序有讀取或寫入? – havexz

回答

3

這一個有點棘手。如果你可以控制或者至少與拷貝文件的程序進行通信,那將是小菜一碟,但是我猜這對於Windows來說是不可能的。我不得不在前段時間用SFU軟件處理類似的問題,我通過循環嘗試打開文件進行寫入直到其可用,從而解決了這個問題。

爲了避免循環時CPU使用率過高,檢查文件可以在an exponential distribution速率下完成。

編輯一個可能的解決方案:

File fileToCopy = File(String pathname); 
int sleepTime = 1000; // Sleep 1 second 
while(!fileToCopy .canWrite()){ 
    // Cannot write to file, windows still working on it 
    Sleep(sleepTime); 
    sleepTime *= 2; // Multiply sleep time by 2 (not really exponential but will do the trick) 
    if(sleepTime > 30000){ 
     // Set a maximum sleep time to ensure we are not sleeping forever :) 
     sleepTime = 30000; 
    } 
} 
// Here, we have access to the file, go process it 
processFile(fileToCopy); 
+0

這聽起來像一個有效的選項。你可以給我一個小的示例代碼,如何實現指數循環,如果它試圖打開文件失敗? – Eosphorus

+0

@ user1074440完成!請看我的編輯。 – GETah

+0

這個工作。非常感謝。然而,filetoCopy.canWrite()或filetoCopy.canRead()將永遠是真實的,即使窗戶有鎖。所以我們需要嘗試打開文件和捕獲異常而不是while循環。再次感謝,我將標記此解決 – Eosphorus

0

我想你可以創建File對象,然後使用canReadcanWrite知道是否文件已準備好由其它Java程序中使用。

http://docs.oracle.com/javase/6/docs/api/java/io/File.html

另一種選擇是試圖在第一個程序打開文件,並在它拋出異常然後不調用其他Java程序。但我會推薦以上'File選項。

+2

canRead實際上並未說明該文件是否已準備好被另一個程序使用。我試圖在文件正在被複制的過程中使用它,但奇怪的是,當我期待一個錯誤,因爲該文件被窗口鎖定時,該值返回true。 – Eosphorus

+0

但你應該嘗試'canWrite' – havexz

+0

canWrite doesn工作要麼悲傷:( – Eosphorus

4

非常感謝所有幫助,我是有WatchEvent同樣的問題。 不幸的是,正如你所說的,即使文件仍然被Windows鎖定,file.canRead()和file.canWrite()都返回true。所以我發現,如果我嘗試用相同的名稱「重命名」它,我知道Windows是否在使用它。所以這就是我所做的:

while(!sourceFile.renameTo(sourceFile)) { 
     // Cannot read from file, windows still working on it. 
     Thread.sleep(10); 
    } 
+1

這是一個很好的解決方法@jfajunior。我以類似的方式做了。我只是試圖打開該文件,它會給出一個例外,因爲Windows正在處理它。所以我發現異常讓線程像你一樣睡覺,並在上述建議的指數循環之後再次嘗試。很高興這篇文章幫助你 – Eosphorus

相關問題