使用walkFileTree进行Java线程处理

时间:2017-01-12 11:28:43

标签: java

我是java线程进程的新手,我找到了一些示例代码,我有兴趣知道他们的代码是如何流动的,所以我可以把它放到我的代码中。这是我reference。我将使用Files.walkFileTree()使用WatchService在主目录和子目录中注册所有新创建的文件夹
这是我的示例文件夹结构

Root : C:/REST API/source/
sub directory : /source/abc/



首先,我将使用WatchService注册我的根目录,并创建folder abc。但是,当我尝试像之前描述的那样进行测试时,我无法完全理解编译调试消息的流程

这是我的编译器消息

Register path for Watcher Service
The Main Path is :C:\REST API\source
The sub path is :C:\REST API\source
In RegisterDIR method () path valueC:\REST API\source
Register path for Watcher Service
The Main Path is :C:\REST API\source
The sub path is :C:\REST API\source
In RegisterDIR method () path valueC:\REST API\source
The Main Path is :C:\REST API\source
The sub path is :C:\REST API\source\New folder
In RegisterDIR method () path valueC:\REST API\source\New folder
Register path for Watcher Service
The Main Path is :C:\REST API\source
The sub path is :C:\REST API\source
In RegisterDIR method () path valueC:\REST API\source
The Main Path is :C:\REST API\source
The sub path is :C:\REST API\source\abc
In RegisterDIR method () path valueC:\REST API\source\abc


这是我的示例代码

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

public  class AbsolutePath<WatchListener>
{
    static Path mainPath;
    static WatchService svc;
    Thread watch;
    static Map <WatchKey , Path> keyMap;
    WatchKey wk;
    Timer timer;
    WatchListener lin;


    public static void main(String [] args ) throws IOException
    {

        mainPath = Paths.get("C:/REST API/source/");

        svc =  FileSystems.getDefault().newWatchService();

        keyMap = new HashMap<>();

        AbsolutePath ab = new AbsolutePath();

        ab.start();
    }

    private void start() throws IOException
    {

        watch = new Thread(new Runnable()
              {
                 public void run()
                 {
                    if(!Thread.currentThread().isInterrupted()) 
                    {

                        walkTreeAndSetWatches();
                        while(true)
                        {
                            try 
                            {

                                wk = svc.take();

                                wk.pollEvents();

                                wk.reset();

                                newRegister();

                            } 
                            catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }
                 }

              });

      watch.start();
    }
    private synchronized void walkTreeAndSetWatches()
    {
        System.out.println("Register path for Watcher Service");
        try
        {
            Files.walkFileTree(mainPath, new FileVisitor<Path>()
            {
                @Override
                public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attr) throws IOException 
                {
                     System.out.println("The Main Path is :"+mainPath);
                     System.out.println("The sub path is :"+path);
                    if(attr.isDirectory())
                    {

                         registerDIR(path);
                    }
                    return FileVisitResult.CONTINUE;
                }



                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException 
                {

                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException 
                {

                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException 
                {

                    return FileVisitResult.CONTINUE;
                }


            });
        }
        catch(IOException io)
        {
            io.printStackTrace();
        }
    }

    private void registerDIR(Path path) 
    {
        try 
        {
             System.out.println("In RegisterDIR method () path value"+path);
             keyMap.put(path.register(svc, StandardWatchEventKinds.ENTRY_CREATE),path);

        }

        catch (IOException e) 
        {
           e.printStackTrace();
        }

    }

     private synchronized void newRegister() 
    {
      timer = new Timer();

      timer.schedule(new TimerTask()
              {

                @Override
                public void run() 
                {

                    walkTreeAndSetWatches();


                }


              },3000);
    }

}


有人可以帮我理解为什么我的代码流变得像那样,是不是因为线程处理有问题?在我的参考链接中,如果在受监控目录中创建了文件夹/文件,他们如何处理他们的事件,因为我无法找到它如何处理此类事件

1 个答案:

答案 0 :(得分:1)

发生这种情况是因为在你的while循环中你调用newRegister(),而newRegister()又从mainPath走来,这是静态的。 一些建议:

  • 重构代码以便没有静态,
  • 这是一个递归算法,因此您需要在注册新路径时将新路径传递给新的walker。

其他问题:原始代码中你不喜欢什么让你重写它? :)(另一种方式:你想添加/删除哪种功能?)