2010-03-29 71 views
9

我需要能夠用Java模擬'tail -f'。我試圖讀取一個日誌文件,因爲它正在被另一個進程寫入,但是當我打開文件來讀取它時,它會鎖定文件,而另一個進程無法再寫入它。任何幫助將不勝感激!Java:在不鎖定的情況下從文件中打開並讀取

這裏是我目前使用的代碼:

public void read(){ 
    Scanner fp = null; 
    try{ 
     fp = new Scanner(new FileReader(this.filename)); 
     fp.useDelimiter("\n"); 
    }catch(java.io.FileNotFoundException e){ 
     System.out.println("java.io.FileNotFoundException e"); 
    } 
    while(true){ 
     if(fp.hasNext()){ 
      this.parse(fp.next()); 
     }   
    }  
} 
+0

如果沒有別的辦法,你可以(無論API,您正在使用假設你使用的是Windows,否則)使用JNI去Win32 API的。 – Blindy 2010-03-29 10:59:21

+1

使用Win32 API將是最醜陋的東西;) – Bozho 2010-03-29 11:02:01

+0

嘿,因爲我不知道Java中好,這是我最好的建議:) – Blindy 2010-03-29 11:03:04

回答

0

看那FileChannel API here。爲了鎖定文件,你可以檢查here

+0

你可以看看在stackoverflow可能重複的問題在http://stackoverflow.com/questions/128038/how-can-i-lock-a-file-使用-java-if-possible – Cshah 2010-03-29 11:03:05

+0

嗯。我一直在關注它,並嘗試了幾種策略 - 即使使用FileChannel之外的java.io.RandomAccessFile,但我仍然無法設法讓另一個進程寫入我正在用Java讀取的文件。 – rogue780 2010-03-29 22:37:22

+0

rogue780 - 發佈你試過的策略。請注意,如果其他進程在寫入文件之前需要獨佔鎖,那麼您幾乎要烤麪包(當然,在這種情況下,尾巴也不起作用)。但是你有沒有試過用非獨佔的讀鎖來鎖定文件的頂部? – 2010-03-30 04:17:03

0

Windows使用的文件強制鎖定,除非你,而你打開指定權份額標誌。如果您想打開一個忙碌文件,則需要使用共享標誌FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE的句柄Win32-API CreateFile

這是使用JDK裏面的幾個地方打開文件進行讀取屬性和東西,但據我可以看到它不會導出/可用於Java類庫的水平。所以你需要找到一個本地庫來做到這一點。

我覺得作爲一個快速的工作你周圍可以從命令"cmd /D/C type file.lck"

+1

我不確定它何時更改,但使用RandomAccessFile打開的文件用SHARE_READ和SHARE_WRITE打開。我使用ProcMon.exe進行了測試 – kervin 2015-10-16 23:11:29

0

閱讀process.getInputStream()如果你想有一個快速的解決方案,這可能不是最優雅,簡單地監視大小變化的文件,然後打開該文件,尋求到最後的位置,閱讀新的數據,關閉文件,並繼續監控。

如果性能是不是一個問題,這應該只是罰款。但是,如果您需要性能,則應優先考慮基於某些更高級的文件IO API的更復雜的解決方案。

+0

如果由於鎖定而無法打開它,請不要使用它。 – EJP 2014-11-12 03:26:22

5

重建尾是棘手的,由於一些特殊情況下,像文件截斷和(中間)刪除。要打開文件沒有鎖定使用StandardOpenOption.READ新的Java文件API,像這樣:

try (InputStream is = Files.newInputStream(path, StandardOpenOption.READ)) { 
    InputStreamReader reader = new InputStreamReader(is, fileEncoding); 
    BufferedReader lineReader = new BufferedReader(reader); 
    // Process all lines. 
    String line; 
    while ((line = lineReader.readLine()) != null) { 
     // Line content content is in variable line. 
    } 
} 

對於我試圖在Java中創建一個尾巴看到:

隨意從該代碼中獲取靈感或者只需複製所需的部件。如果您發現任何我不知道的問題,請告訴我。

相關問題