如何有效监控远程位置的变化?

时间:2011-03-01 17:07:35

标签: java algorithm parsing diff

我们必须监控远程系统文件的变化,我们通过FTP,SMB访问。 我们没有任何SSH访问远程系统/ OS。我们唯一的远程系统视图是FTP或Samba让我们看到的。

我们今天做的事情:

定期扫描整个目录,在内存中构造一个表示来做我们的东西,然后将它与我们在数据库中的内容合并。

我们想做什么:

能够确定目录是否已更改,因此是否需要解析。理想情况下,永远不必进行完整的解析。我们不想太依赖操作系统功能(inode ...),因为它可能会从安装变为另一个。

主要目标:当数据量非常大时,此过程开始变慢。此日期中只有几个是新的,需要进行解析。如何解析并向我们的数据库添加此部分?

我们此时讨论的主要内容:

  • 检查文件夹的大小
  • 在文件上使用校验和
  • 检查文件夹/文件的最后修改日期

我们真正想要的是什么:

一些输入和最佳实践,因为这个问题变得非常普通,并且应该已经讨论了bean,并且我们不想在这一点上做一些过于复杂的事情。

提前致谢,一群同行的开发人员; - )

我们使用java / spring / hibernate堆栈,但我认为这不重要。

编辑:基本上,我们访问FTP服务器或同等产品。本地副本不是一个选项,因为数据量很大。

4 个答案:

答案 0 :(得分:3)

Java远程目录轮询器(rdp4j)库可以帮助您轮询FTP位置并通过以下事件通知您:文件在目录中添加/删除/修改。它使用lastModified日期为目录中的每个文件,并将它们与之前的轮询进行比较。

查看完整的User Guide,其中包含以下API快速教程中FtpDirectoryMyListener的实现:

package example

import java.util.concurrent.TimeUnit;
import com.github.drapostolos.rdp4j.DirectoryPoller;
import com.github.drapostolos.rdp4j.spi.PolledDirectory;

public class FtpExample {

    public static void main(String[] args) throws Exception {
        String host = "ftp.mozilla.org";
        String workingDirectory = "pub/addons";
        String username = "anonymous";
        String password = "anonymous";
        PolledDirectory polledDirectory = new FtpDirectory(host, workingDirectory, username, password);

        DirectoryPoller dp = DirectoryPoller.newBuilder()
        .addPolledDirectory(polledDirectory)
        .addListener(new MyListener())
        .setPollingInterval(10, TimeUnit.MINUTES)
        .start();

        TimeUnit.HOURS.sleep(2);

        dp.stop();
    }
}

答案 1 :(得分:2)

您无法使用目录大小或修改日期来判断子目录是否已更改。完全停止。至少你必须做一整个树的完整目录列表。

如果您满意,您可以避免阅读文件内容,您可以依赖于修改日期和时间的组合。

我的建议是使用现成的软件创建本地克隆(例如rsync,robocopy),然后对本地克隆进行比较/解析。然后,问题“它是否已更新”是rsync要回答的问题。

答案 2 :(得分:2)

如前所述,您无法通过FTP或SMB跟踪目录。您可以做的是列出远程服务器上的所有文件并构建包含以下内容的快照:

  • for file:名称,大小和修改日期,
  • 用于目录:名称及其内容中的最新修改日期

使用此信息,您将能够确定需要查看哪些目录以及需要传输哪些文件。

答案 3 :(得分:1)

安全便携的解决方案是使用强哈希/校验和,例如SHA1或(最好)SHA512。哈希可以映射到您想要计算和存储的任何表示。您可以使用以下recursive recipe(改编自Git版本控制系统):

  1. 文件的哈希值是其内容的哈希值,忽略名称;
  2. 对目录进行哈希处理,将其视为文本表示形式的文件名 - 哈希对的排序列表,并将其作为哈希值。
  3. 在散列之前,可能会先将f添加到每个文件中,然后d添加到每个目录表示中。

    您还可以使用Git(或Mercurial,或任何您喜欢的内容)将目录置于版本控制之下,定期git add其中的所有内容,使用git status查找更新内容,以及{{ 1}}变化。