我正在用java(1.6)中的目錄監視實用程序以一定的時間間隔使用輪詢,使用lastModified
long值作爲更改的指示。我發現,當我的輪詢時間間隔很小(秒)並且複製的文件很大時,在實際完成文件複製之前觸發更改事件。如何知道java中是否正在進行文件複製/完成(1.6)
我想知道是否有方法可以讓我找到像在運輸文件的狀態,完整等
環境:Java 1.6的;預計將在Windows和Linux上工作。
我正在用java(1.6)中的目錄監視實用程序以一定的時間間隔使用輪詢,使用lastModified
long值作爲更改的指示。我發現,當我的輪詢時間間隔很小(秒)並且複製的文件很大時,在實際完成文件複製之前觸發更改事件。如何知道java中是否正在進行文件複製/完成(1.6)
我想知道是否有方法可以讓我找到像在運輸文件的狀態,完整等
環境:Java 1.6的;預計將在Windows和Linux上工作。
你的意思是說你在等待lastModified
的時間解決?最好這會有點碰碰運氣。
如何試圖用寫權限打開文件(當然是附加文件而不是截斷文件)?如果另一個進程仍在嘗試寫入,它將不會成功。這有點難看,特別是它可能是流量控制(ick)使用異常的情況,但我認爲它會起作用。
這不是假設您有權訪問受監視的目錄嗎? (我沒有更好的主意,介意......) – 2009-04-15 06:19:01
Thanks.I嘗試了這種方法,它適用於我的開發機器,但與之前的評論相同,因爲我不確定部署用戶權限 – 2009-04-15 06:26:51
@simonn:是的,這取決於你是否擁有寫權限,而不是依賴於目錄,而是依賴於文件。 – 2009-04-15 08:08:47
如果我正確理解問題,您正在尋找一種方法來區分文件的複製是完成還是仍在進行中?
如何比較源文件和目標文件(即file.length())的大小?如果它們相同,則複製完成。否則,它仍在進行中。
我不確定它是否有效,因爲它仍然需要輪詢。但它「可能」起作用。
我曾經使用過兩種方法,它們是平臺不可知的。
1 /這是用於FTP傳輸,我控制放置的內容,因此可能不直接相關。
基本上,無論是把一個文件file.txt
,它將完成時,還將一個小的(可能是零字節)虛擬文件,稱爲file.txt.marker
(例如)。
這樣,監視工具只是查找要出現的標記文件,並且當它發生時,它知道真實文件已完成。然後它可以處理真實文件並刪除標記。
2 /持續時間不變。
讓您的監視器程序等待,直到文件未更改N秒(其中N合理保證足夠大以至文件將完成)。
例如,如果文件大小在60秒內沒有改變,那麼它很有可能完成。
在不考慮文件完成之間有一個平衡行爲,只是因爲它沒有活動,並且在它開始處理之前等待完成。與FTP相比,這對於本地複製來說不是一個問題。
您可以使用進度條技術研究在線文件上傳 - 它們使用OutputStreamListener和自定義寫入器向偵聽器通知寫入的字節。
http://www.missiondata.com/blog/java/28/file-upload-progress-with-ajax-and-java-and-prototype/
該解決方案爲我工作:
File ff = new File(fileStr);
if(ff.exists()) {
for(int timeout = 100; timeout>0; timeout--) {
RandomAccessFile ran = null;
try {
ran = new RandomAccessFile(ff, "rw");
break; // no errors, done waiting
} catch (Exception ex) {
System.out.println("timeout: " + timeout + ": " + ex.getMessage());
} finally {
if(ran != null) try {
ran.close();
} catch (IOException ex) {
//do nothing
}
ran = null;
}
try {
Thread.sleep(100); // wait a bit then try again
} catch (InterruptedException ex) {
//do nothing
}
}
System.out.println("File lockable: " + fileStr +
(ff.exists()?" exists":" deleted during process"));
} else {
System.out.println("File does not exist: " + fileStr);
}
該解決方案依賴於一個事實,你不能打開文件寫,如果另一個進程已經打開。它將保持在循環中,直到達到超時值或文件可以打開。超時值將需要根據應用程序的實際需求進行調整。我也嘗試過使用channel和tryLock()的方法,但似乎沒有必要。
我們用來監視文件大小的變化,以確定文件是否在inComplete中。
我們使用了Spring集成文件端點爲每200毫秒執行一次目錄輪詢。
一旦檢測到文件(無論它是否完整),我們有一個客戶文件過濾器,它將有一個接口方法「接受(文件文件)」返回一個標誌,指示我們是否可以處理文件。
如果假被過濾器返回的,這個文件實例將被忽略,這將是相同的過濾過程的下一個輪詢期間拿起..
過濾器執行以下操作:
首先,我們得到它當前的文件大小。我們將等待200ms(可以少一些)並再次檢查大小。如果大小不同,我們會重試5次。只有當文件大小停止增長時,文件纔會被標記爲COMPLETED(即返回true)。使用
示例代碼如下:
public class InCompleteFileFilter<F> extends AbstractFileListFilter<F> {
protected Object monitor = new Object();
@Override
protected boolean accept(F file) {
synchronized (monitor){
File currentFile = (File)file;
if(!currentFile.getName().contains("Conv1")){return false;}
long currentSize = currentFile.length();
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
int retryCount = 0;
while(retryCount++ < 4 && currentFile.length() > currentSize){
try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
}
if(retryCount == 5){
return false;
}else{
return true;
}
}
}
}
我認爲你有逆轉的「重複」的方面。這在2009年被問到,另一個在2013年被問到! – 2015-02-22 14:19:04