【问题标题】:How to watch file for new content and retrieve that content如何查看文件中的新内容并检索该内容
【发布时间】:2014-06-19 07:55:32
【问题描述】:

我有一个名为 foo.txt 的文件。该文件包含一些文本。我想实现以下功能:

  1. 我启动程序
  2. 向文件中写入内容(例如添加一行:new string in foo.txt
  3. 我只想获取此文件的新内容。

你能阐明这个问题的最佳解决方案吗?我也想解决相关问题:如果我修改foo.txt,我想看看差异。

我在 Java 中找到的最接近的工具是 WatchService,但如果我理解正确,这个工具只能检测文件系统上发生的事件类型(创建文件或删除或修改)。

【问题讨论】:

  • Java Diff Utils 可能有帮助
  • 只用这个文件是不可能得到区别的,除非你能确保每一个修改都是一个附件。
  • @J.Rush 有可能,Java Diff Utils 确实做到了。它基于保存在不同列表中的内容进行文件比较。实际上,您可以将原始文件保存在一个列表中,并在编辑时将其加载到另一个列表中,然后比较两个列表以查看差异。
  • @BackSlash,我认为您提到的列表必须存储在其他文件中,对吗?

标签: java io filesystems diff watchservice


【解决方案1】:

Java Diff Utils 就是为此目的而设计的。

final List<String> originalFileContents = new ArrayList<String>();
final String filePath = "C:/Users/BackSlash/Desktop/asd.txt";

FileListener fileListener = new FileListener() {

    @Override
    public void fileDeleted(FileChangeEvent paramFileChangeEvent)
    throws Exception {
        // use this to handle file deletion event

    }

    @Override
    public void fileCreated(FileChangeEvent paramFileChangeEvent)
    throws Exception {
        // use this to handle file creation event

    }

    @Override
    public void fileChanged(FileChangeEvent paramFileChangeEvent)
    throws Exception {
        System.out.println("File Changed");
        //get new contents
        List<String> newFileContents = new ArrayList<String> ();
        getFileContents(filePath, newFileContents);
        //get the diff between the two files
        Patch patch = DiffUtils.diff(originalFileContents, newFileContents);
        //get single changes in a list
        List<Delta> deltas = patch.getDeltas();
        //print the changes
        for (Delta delta : deltas) {
            System.out.println(delta);
        }
    }
};

DefaultFileMonitor monitor = new DefaultFileMonitor(fileListener);
try {
    FileObject fileObject = VFS.getManager().resolveFile(filePath);
    getFileContents(filePath, originalFileContents);
    monitor.addFile(fileObject);
    monitor.start();
} catch (InterruptedException ex) {
    ex.printStackTrace();
} catch (FileNotFoundException e) {
    //handle
    e.printStackTrace();
} catch (IOException e) {
    //handle
    e.printStackTrace();
}

getFileContents 在哪里:

void getFileContents(String path, List<String> contents) throws FileNotFoundException, IOException {
    contents.clear();
    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));
    String line = null;
    while ((line = reader.readLine()) != null) {
        contents.add(line);
    }
}

我做了什么:

  1. 我在List&lt;String&gt; 中加载了原始文件内容。
  2. 我使用Apache Commons VFS 来监听文件更改,使用FileMonitor。您可能会问,为什么?因为WatchService 仅从 Java 7 开始可用,而FileMonitor 至少适用于 Java 5(个人喜好,如果您更喜欢 WatchService 可以使用它)。 注意:Apache Commons VFS 依赖于Apache Commons Logging,您必须将两者都添加到您的构建路径中才能使其正常工作。
  3. 我创建了一个FileListener,然后我实现了fileChanged 方法。
  4. 该方法从文件中加载新内容,并使用Patch.diff 检索所有差异,然后打印它们
  5. 我创建了一个DefaultFileMonitor,它主要监听文件的更改,然后我将我的文件添加到其中。
  6. 我启动了监视器。

监视器启动后,它将开始侦听文件更改。

【讨论】:

  • 你忘了添加方法getFileContents的实现
  • @gstackoverflow 添加了它。我对WatchService 不是很熟悉,一个很好的起点是Oracle Tutorials 关于它的页面。
  • 如果在处理事件的那一刻发生了新事件,那么奇怪的行为
  • 如果您有更多信息 - 请在以后添加它
  • @G.Urikh 我不知道。肯定有用于区分文件的工具可以节省内存,但我认为文件系统不会为此目的公开 API,尽管它们可以在内部使用它来有效地存储文件更改。您可能必须编写自己的代码才能从两个文件中读取小块并计算差异,而不会占用太多内存(如果幸运的话,有人已经这样做并共享了代码)。
猜你喜欢
  • 2016-03-03
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多