通过 SFTP 从服务器读取巨大的动态文件的结尾

Reading end of huge and dynamic file via SFTP from server

我正在尝试找到一种方法来通过 SFTP 从服务器读取巨大的动态日志文件的结尾(比如从结尾开始的 20-30 行)并将该点保存到我读取的位置,如果我需要更多行,从这里开始阅读更多。

我尝试过的所有操作都花费了太长时间,我尝试在机器上复制此文件,然后使用 ReversedLinesFileReader 从末尾读取,因为此方法需要 File 对象,当通过 SFTP 时,您只会获得 InputStream,下载文件需要很多时间。

还尝试计算行数并从 n 行读取,但也花费了太长时间并抛出异常,因为此时文件已被修改。另一种方法是我尝试通过 SSH 连接并使用 tail -100 并获得所需的结果,但只是一次,因为下次我也会获得新日志,但我需要上层。有没有一种快速的方法来获取文件末尾并保存该点并稍后阅读该点的更多内容?有什么想法吗?

最好是有一种循环日志文件,可能带有压缩。

rsync 是单向同步,它只能传输文件的更改部分:对于日志,新的结尾。

我不确定它在您的情况下是否足够高效,ssh 是先决条件。

你没有说你使用的是什么 SFTP 库,但使用最广泛的 Java SSH/SFTP 库是 JSch,所以我假设你正在使用那。

SFTP protocol has operations to perform random-access I/O on remote files. Unfortunately, the JSch SFTP client doesn't expose the full range of operations. However, it does have versions of the get operation(用于从远程服务器获取文件)允许跳过远程文件的第一部分。例如,您可以使用这些操作之一来读取文件的最后 10 KB。

几个 JSch get 操作 return 和 InputStream。您可以从输入流中读取远程文件的内容。如果要访问远程文件line-by-line,可以将其转换为Reader using InputStreamReader.

因此,进程可能会执行以下操作:

  1. 对远程文件调用 stat() 以获取其大小。
  2. 确定您要从文件中的哪个位置开始读取。您可以跟踪上次停止阅读的位置,或者您可以根据您愿意下载的数据量和最后 20-30 行的预期字节大小进行猜测。
  3. 致电 get() 开始阅读。
  4. 通过 get() 调用从 InputStream return 中读取的处理数据。