当前位置: 首页 > 面试题库 >

如何在Java中像“ Tail -f”一样跟踪文件而又不保持打开状态(防止重命名/删除)

王修为
2023-03-14
问题内容

我想从Java应用程序中“拖尾-f”很多日志文件。

我已经通过监视大小和上次更新并重复打开文件并在文件大小或上次更新时间更改时读取最后几个字节来工作,然后立即将其关闭。

这似乎有问题,因为当记录程序决定重命名文件时,我可能会打开它,这将导致某种问题。

我还想用一种机制来检测“滚动”文件,而不是注意减小文件大小……似乎容易出错,但不太可能。

由于我似乎无法访问文件描述符或其他低级文件实用程序,因此我可能无法重现tail的行为-但是有任何技巧可以在不“锁定”文件以进行重命名/删除的情况下读取文件(
Windows 7的)

我猜另一种可能性是实际上产生一个tail -f进程并读取该进程的输出,但这似乎有些沉重-
我在这里扫描60个日志文件,其中一些具有很多输出(大多数将处于空闲状态)。


问题答案:

Apache Commons有一个Tailer类,那么您想要做什么?如果可以的话,它具有滚动检测机制以及阅读功能,因此您将获得所需的一切。

如果那做不到,则可能是纯Java无法实现。您需要一些帮助,例如C代码,将fopen与SH_DENYNO参数一起使用以允许在Windows上共享打开。或者只是通过执行系统命令来调用tail实现。

但是由于打开日志文件的代码是导致对其进行锁定的代码,即使这样做可能也无济于事。在这种情况下,唯一真正的选择是更改日志记录的工作方式,因为这是锁定文件的罪魁祸首。Log4j可以使用SocketAppender等等。



 类似资料:
  • 我正在用实时读取日志文件。这个效果很好。但每天都有一个日志循环,这意味着我的日志文件将被重命名,不再更改。将在同一位置创建新的日志文件。在我可以更改到新的日志文件之前,我需要完成当前日志文件的读取,使用没有问题,但是我如何才能发现文件名已更改? 我试着调用和,但这不起作用,因为-objects路径在创建后是固定的。 我还尝试使用WatchService,但附加到文件后也会导致ENTRY\u DEL

  • 问题内容: 我已经提交了类似的问题,但已将问题分解为最简单的形式,因此我将其再次发布: 问题是,如果我多次添加同一文件,SolrJ似乎会使文件句柄保持打开状态。 我使用以下方法向Solr提交文档: 而这种删除文件的方法: 但这似乎留有一些文件句柄: 以下代码段演示了该问题: 如果我两次添加相同的文档,SolrJ会以某种方式使这些句柄保持活动状态,并且添加的文档无法被任何其他进程修改。 我已经尝试调

  • 我有一个命名管道文件,如下所示: 当我在PHP中执行类似操作时: 它挂起(即永不返回)。是否有办法使此呼叫返回和/或超时? (编辑) 请注意,我希望一个进程以写权限打开此管道,另一个进程以读权限打开此管道。有人在向这根管子写信,而另一个人在从这根管子读书。问题是读者有时会挂在fopen()上——不管它成功与否,我总是想返回它。

  • 问题内容: 我对JDK7中的所有这些新文件I / O类感到困惑。 假设我有一个,并且想重命名它代表的文件。再次输入a时,如何指定新名称? 注意:为什么我需要 JDK7 ?处理 符号链接 ! 问题是:我必须对名称和位置在运行时已知的文件进行处理。因此,我需要的是一种 安全的 方法(没有特殊的副作用)来创建一些旧名称路径的新名称路径。 问题答案: 您有一个路径字符串,并且需要创建一个Path实例。您可

  • 我正在创建一个URLClassloader来加载一些JAR。每个jar从不同的classloader中正确加载,每个jar包含一个具有run()方法的类。现在这个run()的主体可以在其中创建一个匿名的内部类。但是,因为我在try-with-resources块中创建了我的URLClassloader,所以它会自动关闭,并且在运行时,当它试图加载匿名内部类时,它会抛出一个NoClassDefFou