4

在这段代码中,我希望使用给定路径内容的最新版本更新 HashMap,并将绝对路径作为字符串用作键。问题是WatchEvent' 的.context()方法在每个事件上为我提供了相同文件的不同相对路径。

这是一段代码:

            else if(event.kind()==StandardWatchEventKinds.ENTRY_MODIFY)
            {
                /*Variable path is a Path of "//workspaces", set earlier.*/
                Path oldfilepath=path.resolve((Path)event.context()); /*problem line*/
                String oldfilepathstring = oldfilepath.toString();
                 FileReader oldIn = new FileReader(oldfilepathstring);
                 BufferedReader br = new BufferedReader(oldIn);
                 String line;
                 List<String> newfiletext=new LinkedList<>();
                  while((line = br.readLine())!=null)
                    newfiletext.add(line);

                 List<String> previousText=new LinkedList<>();
                 if((previousText = fileMappings.get(oldfilepathstring))!= null)
                 {
                      System.out.println("previoustext:\n"+previousText);
                      System.out.println("newfiletext:\n"+newfiletext);
                 }

                 fileMappings.put(oldfilepathstring, newfiletext);
                 System.out.println(fileMappings.keySet()+"\n"+fileMappings.values());
            }

        }

这是b.txt将监视目录中的文件从内容“abc”修改为“abc 123”后的示例输出

请注意,所有这些都来自打开文件 /workspaces/b.txt (已经存在)并修改其内容。)

    跑:
    ENTRY_CREATE:.goutputstream-BRC1HX
    ENTRY_MODIFY:.goutputstream-BRC1HX
    [/workspaces/.goutputstream-BRC1HX]
    [[]]
    ENTRY_MODIFY:.goutputstream-BRC1HX
    上一篇:
    []
    新文件文本:
    [ABC]
    [/workspaces/.goutputstream-BRC1HX]
    [[ABC]]
    ENTRY_CREATE:b.txt~
    ENTRY_CREATE:b.txt
    ENTRY_CREATE:.goutputstream-MFJ6HX
    ENTRY_MODIFY:.goutputstream-MFJ6HX
    [/workspaces/.goutputstream-MFJ6HX, /workspaces/.goutputstream-BRC1HX]
    [[], [abc]]
    ENTRY_MODIFY:.goutputstream-MFJ6HX
    上一篇:
    []
    新文件文本:
    [美国广播公司,123]
    [/workspaces/.goutputstream-MFJ6HX, /workspaces/.goutputstream-BRC1HX]
    [[abc, 123], [abc]]
    ENTRY_CREATE:b.txt~
    ENTRY_CREATE:b.txt

感兴趣的线是 Path oldfilepath=path.resolve((Path)event.context());

请注意如何oldfilepath将同一文件解析为“/workspaces/.goutputstream-MFJ6HX”,然后再解析为“/workspaces/.goutputstream-BRC1HX”。

event.context()每次修改后为同一文件返回不同的路径。这是 Linux 问题还是 Java 问题,我究竟如何获得该文件的标准相对路径(在这种情况下,它是“b.txt”)?

似乎当我执行修改时,我得到了一系列创建/修改/创建事件,并且ENTRY_CREATEs 具有正确的文件名,同时ENTRY_MODIFYs 具有临时句柄(我猜是文件的临时版本在保存之间使用。)我需要能够捕获文件修改并从该事件中提取正确的文件名。

我知道我的文件系统可能在我刚刚打开、修改和保存文件时在后台进行临时文件创建和处理,但是如何从事件指示ENTRY_MODIFY给我的临时文件中提取正确的文件名?是否有某种方法可以对与此修改有关的事件进行分组,以便我可以找到附件ENTRY_CREATE并从中获取文件名?或者以某种方式向上遍历导致此的调用堆栈ENTRY_CREATE

我可以在封闭事件中看到文件名ENTRY_CREATE,围绕 each ENTRY_MODIFY,但我希望有一种比某种更优雅的方法来做到这一点(获取不是的最新事件,ENTRY_MODIFY然后从中获取.context()。)

谢谢!

4

2 回答 2

6

我面临同样的问题。我认为这与任何 Linux 问题或任何 Java 问题无关。这正是 b.txt 的编辑器(我假设是 gedit)处理事情的方式。

保存后

  1. 使用一些随机 xxxx(您看到的创建)创建一个新的临时文件“.goutputstream-xxxx”,

  2. 将新内容写入此文件(您看到的修改),

  3. 将原始文件重命名为 b.txt~ (你看到的创建),

  4. 并将临时文件重命名为 b.txt (您看到的创建)

所以我想你必须注意关于 b.txt 的 ENTRY_MODIFY 和 ENTRY_CREATE 才能真正看到所有文件修改。

于 2014-06-21T10:12:22.970 回答
0

我有同样的问题。我使用过滤器来排除这个问题。例如:我需要路径/home/user/data/in中的所有文件;

Files.walk(Paths.get( System.getProperty("user.home").concat("/data/in")))
                    .map(Path::toString)
                    .filter(path -> ! path.endsWith("/in"))
                    .filter(path -> ! path.startsWith(".goutputstream"))
                    .collect(Collectors.toList());

这对我来说是修复。

于 2020-08-12T09:35:18.960 回答