如何在不保持文件打开的情况下在 Java 中跟踪像“Tail -f”这样的文件(防止重命名/删除)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14610621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I follow a file like "Tail -f" does in Java without holding the file open (Prevent rename/delete)
提问by Bill K
i'd like to "Tail -f" a lot of logfiles from within a java app.
我想从 Java 应用程序中“拖尾 -f”很多日志文件。
I've gotten this to work by monitoring the size and last update and repeatedly opening the file and reading the last few bytes whenever the file size or last update time changes--then closing it right away.
我通过监视大小和上次更新并在文件大小或上次更新时间发生变化时反复打开文件并读取最后几个字节来实现这一点 - 然后立即关闭它。
This seems problematic because I might have it open when the logger decides to rename the file which will cause some kind of problem.
这似乎有问题,因为当记录器决定重命名会导致某种问题的文件时,我可能会打开它。
I'd also like to detect a "Rolled" file with a mechanism more sure than noticing that the file size reduced... seems error prone but unlikely.
我还想检测一个“滚动”文件,其机制比注意到文件大小减少更确定......似乎容易出错但不太可能。
Since I don't seem to have access to the file descriptor or other low-level file utilities I may not be able to reproduce tail's behavor--but are there any tricks to reading a file without "Locking" it for rename/delete (Windows 7)
由于我似乎无法访问文件描述符或其他低级文件实用程序,因此我可能无法重现 tail 的行为——但是是否有任何技巧可以在不“锁定”文件以进行重命名/删除的情况下读取文件( Windows 7的)
I guess another possibility is to actually spawn a tail -f process and read the process output, but that seems somewhat heavy--I'm scanning like 60 logfiles here, some of which have a lot of output (Most will be idle).
我想另一种可能性是实际产生一个 tail -f 进程并读取进程输出,但这似乎有些沉重——我在这里扫描了 60 个日志文件,其中一些有很多输出(大多数会空闲)。
采纳答案by eis
Apache Commons has a Tailer class, would that do what you want? If it would, it has rolling detection mechanism as well as the reading stuff, so you'd get all you need.
Apache Commons 有一个Tailer 类,这会做你想要的吗?如果是这样,它具有滚动检测机制以及读取内容,因此您将获得所需的一切。
If that cannot do it, it might be that there's no way of doing it with pure java. You'd need some help of, for example, C code, utilizing fopen with SH_DENYNOparameter allowing shared open on windows. Or then just call a tail implementation by executing a system command.
如果那不能做到,那可能是没有办法用纯 java 做到这一点。您需要一些帮助,例如 C 代码,使用带有SH_DENYNO参数的fopen允许在 Windows 上共享打开。或者只是通过执行系统命令来调用尾部实现。
But since the code opening the log file is the one causing the lock on it, even that might not help. In that case the only real option is to change the way your logging works, as that is the culprit locking the file. Log4j can use a SocketAppender, among other things.
但是由于打开日志文件的代码是导致锁定它的代码,即使这样也可能无济于事。在这种情况下,唯一真正的选择是更改日志记录的工作方式,因为这是锁定文件的罪魁祸首。Log4j 可以使用SocketAppender等。
回答by stones333
Use apache.commons.io
使用 apache.commons.io
And here is a simple example
这是一个简单的例子
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();
}
}
}
回答by Cratylus
In Linux you would not have a problem since the locking is only advisory
. But in Windows
things are different.
This should depend on the mode that your logger (I assume log4j) opens the file to log.
Looking in this answerfor C#
it seems that there is a parameter dwShareMode
that can be used for this kind of sharing.
在 Linux 中你不会有问题,因为锁定只是advisory
. 但在Windows
事情上有所不同。
这应该取决于您的记录器(我假设是 log4j)打开要记录的文件的模式。
展望这个答案的C#
,似乎有一个参数dwShareMode
,可以用于这种共享。
I believe NIO
would be the way to go. Look if dwShareMode
parameter is available as part of NIO
APIs
我相信NIO
这将是要走的路。查看dwShareMode
参数是否可作为NIO
API 的一部分使用