2009-04-15 26 views
13

我正在用java(1.6)中的目錄監視實用程序以一定的時間間隔使用輪詢,使用lastModified long值作爲更改的指示。我發現,當我的輪詢時間間隔很小(秒)並且複製的文件很大時,在實際完成文件複製之前觸發更改事件。如何知道java中是否正在進行文件複製/完成(1.6)

我想知道是否有方法可以讓我找到像在運輸文件的狀態,完整等

環境:Java 1.6的;預計將在Windows和Linux上工作。

+1

我認爲你有逆轉的「重複」的方面。這在2009年被問到,另一個在2013年被問到! – 2015-02-22 14:19:04

回答

4

你的意思是說你在等待lastModified的時間解決?最好這會有點碰碰運氣。

如何試圖用寫權限打開文件(當然是附加文件而不是截斷文件)?如果另一個進程仍在嘗試寫入,它將不會成功。這有點難看,特別是它可能是流量控制(ick)使用異常的情況,但我認爲它會起作用。

+0

這不是假設您有權訪問受監視的目錄嗎? (我沒有更好的主意,介意......) – 2009-04-15 06:19:01

+0

Thanks.I嘗試了這種方法,它適用於我的開發機器,但與之前的評論相同,因爲我不確定部署用戶權限 – 2009-04-15 06:26:51

+0

@simonn:是的,這取決於你是否擁有寫權限,而不是依賴於目錄,而是依賴於文件。 – 2009-04-15 08:08:47

1

如果我正確理解問題,您正在尋找一種方法來區分文件的複製是完成還是仍在進行中?

如何比較源文件和目標文件(即file.length())的大小?如果它們相同,則複製完成。否則,它仍在進行中。

我不確定它是否有效,因爲它仍然需要輪詢。但它「可能」起作用。

7

我曾經使用過兩種方法,它們是平臺不可知的。

1 /這是用於FTP傳輸,我控制放置的內容,因此可能不直接相關。

基本上,無論是把一個文件file.txt,它將完成時,還將一個小的(可能是零字節)虛擬文件,稱爲file.txt.marker(例如)。

這樣,監視工具只是查找要出現的標記文件,並且當它發生時,它知道真實文件已完成。然後它可以處理真實文件並刪除標記。

2 /持續時間不變。

讓您的監視器程序等待,直到文件未更改N秒(其中N合理保證足夠大以至文件完成)。

例如,如果文件大小在60秒內沒有改變,那麼它很有可能完成。

在不考慮文件完成之間有一個平衡行爲,只是因爲它沒有活動,並且在它開始處理之前等待完成。與FTP相比,這對於本地複製來說不是一個問題。

5

該解決方案爲我工作:

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()的方法,但似乎沒有必要。

1

我們用來監視文件大小的變化,以確定文件是否在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; 
     } 
    } 
    } 
} 
相關問題