[英]How can I follow a file like “Tail -f” does in Java without holding the file open (Prevent rename/delete)
我想在Java應用程序中“尾隨-f”很多日志文件。
我通過監視大小和上次更新並重復打開文件並在文件大小或上次更新時間發生變化時讀取最后幾個字節 - 然后立即關閉它來實現此功能。
這似乎有問題,因為當記錄器決定重命名文件時,我可能會打開它,這會導致某種問題。
我還想檢測一個“Rolled”文件,其機制更加確定,而不是注意到文件大小減少......似乎容易出錯,但不太可能。
由於我似乎無法訪問文件描述符或其他低級文件實用程序,因此我可能無法重現尾部的行為 - 但是有沒有任何技巧來讀取文件而不將其“鎖定”以進行重命名/刪除( Windows 7的)
我想另一種可能性是實際產生一個尾部-f進程並讀取進程輸出,但這看起來有點沉重 - 我在這里掃描了60個日志文件,其中一些有很多輸出(大部分將是空閑的)。
Apache Commons有一個Tailer類 ,會做你想要的嗎? 如果它,它有滾動檢測機制以及閱讀材料,所以你得到你所需要的一切。
如果不能做到這一點,可能就是沒有辦法用純java做到這一點。 您需要一些幫助,例如,C代碼,利用帶有SH_DENYNO參數的fopen,允許在Windows上共享打開。 或者通過執行系統命令調用尾部實現。
但是,由於打開日志文件的代碼是導致其鎖定的代碼,即使這可能沒有幫助。 在這種情況下,唯一真正的選擇是更改日志記錄的工作方式,因為這是鎖定文件的罪魁禍首。 Log4j可以使用SocketAppender等。
使用apache.commons.io
這是一個簡單的例子
public class LogTailTest {
/**
* TailerListener implementation.
*/
static public class ShowLinesListener extends TailerListenerAdapter {
@Override
public void handle(String line) {
System.out.println(line);
}
}
public static void main(String args[]) {
TailerListener listener = new ShowLinesListener();
File file = new File("./test.log");
Tailer tailer = new Tailer(file, listener, 1000);
tailer.run();
try {
Thread.sleep(100000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
tailer.stop();
}
}
在Linux中你不會有問題,因為鎖定只是advisory
。 但在Windows
情況有所不同。
這應該取決於您的記錄器(我假設log4j)打開要記錄的文件的模式。
看看這個C#
答案 ,似乎有一個參數dwShareMode
可以用於這種共享。
我相信NIO
將是最佳選擇。 查看dwShareMode
參數是否可用作NIO
API的一部分
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.