java无法连续读取/监视远程文件
我使用JSCH尝试在一个不断更新的独立服务器上读取日志文件。我可以很好地提取文件中当前的任何内容,但一旦到达文件末尾,就会出现延迟,但不会提取新行,并且延迟打印语句会继续循环(我通过在程序旁边的日志上运行尾部来验证)。如果有人能指出我的代码中可能有错误或遗漏的地方,或者提出更好的方法,我将不胜感激
InputStream stream = sftpClient.get(filename);
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line;
while (true)
{
try
{
line = br.readLine();
if (line == null)
{
System.out.println("End of file reached. Sleeping..");
Thread.sleep(sleepTime);
System.out.println("Retrying for more data..");
}
else
{
//do something with line, print for now.
System.out.println(line);
}
}
catch (Exception e)
{
System.out.println("Something went wrong: " + e);
}
}
# 1 楼答案
为了补充crv提到的内容,下面是一个关于如何使用Apache
Tailor
的示例# 2 楼答案
您可以看到Jsch的
ChannelSftp
here的源代码。获取远程文件时的InputStream returned by jsch在读取到远程文件末尾时设置一个标志。继续尝试从流中读取只会返回缓存的EOF指示Jsch有a ^{} method to retrieve information about a remote file ,包括其大小和上次修改的时间戳。Jsch还有a version of the get method,它允许您跳过远程文件的第一部分。您可以定期调用stat()来检测文件是否已更改,然后使用get()跳过文件中已读取的部分,然后只读取新内容
您可能还想考虑使用不同的SSH客户端库。SFTP protocol包含用于打开远程文件并读取或写入文件任意部分的低级命令。然而,Jsch并没有通过ChannelSftp公开此功能的全部范围。还有其他java SFTP客户端库提供对SFTP协议的低级访问
# 3 楼答案
我想你应该在结束时重新打开文件。 如果出于生产目的,请尝试使用ApacheTailer https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/Tailer.html
# 4 楼答案
我正在尝试这个,在我的例子中,我必须不断地读取日志,但我只能通过sftp访问它,正如@Kenster提到的,我通过调用
stat()
检查文件大小是否发生了变化,然后使用get( String src, String dst, SftpProgressMonitor monitor, int mode)
,它所做的是在我的目录中生成一个新文件,并且使用RESUME
中的mode参数,它只接受最新的内容