查看目录中的Java更改

查看目录中的Java更改,java,file,java.nio.file,Java,File,Java.nio.file,我想查看目录中的文件更改。我在java.nio中使用了WatchService。我可以成功侦听文件创建事件。但我无法侦听文件修改事件。我检查了一下,但仍在挣扎 这是源代码 import static java.nio.file.LinkOption.NOFOLLOW_LINKS; import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; import static java.nio.file.StandardWatchEv

我想查看目录中的文件更改。我在java.nio中使用了WatchService。我可以成功侦听文件创建事件。但我无法侦听文件修改事件。我检查了一下,但仍在挣扎

这是源代码

import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class MainWatch {

    public static void watchDirectoryPath(Path path) {
        // Sanity check - Check if path is a folder
        try {
            Boolean isFolder = (Boolean) Files.getAttribute(path,
                    "basic:isDirectory", NOFOLLOW_LINKS);
            if (!isFolder) {
                throw new IllegalArgumentException("Path: " + path
                        + " is not a folder");
            }
        } catch (IOException ioe) {
            // Folder does not exists
            ioe.printStackTrace();
        }

        System.out.println("Watching path: " + path);

        // We obtain the file system of the Path
        FileSystem fs = path.getFileSystem();

        // We create the new WatchService using the new try() block
        try (WatchService service = fs.newWatchService()) {

            // We register the path to the service
            // We watch for creation events
            path.register(service, ENTRY_CREATE);
            path.register(service, ENTRY_MODIFY);
            path.register(service, ENTRY_DELETE);

            // Start the infinite polling loop
            WatchKey key = null;
            while (true) {
                key = service.take();

                // Dequeueing events
                Kind<?> kind = null;
                for (WatchEvent<?> watchEvent : key.pollEvents()) {
                    // Get the type of the event
                    kind = watchEvent.kind();
                    if (OVERFLOW == kind) {
                        continue; // loop
                    } else if (ENTRY_CREATE == kind) {
                        // A new Path was created
                        Path newPath = ((WatchEvent<Path>) watchEvent)
                                .context();
                        // Output
                        System.out.println("New path created: " + newPath);
                    } else if (ENTRY_MODIFY == kind) {
                        // modified
                        Path newPath = ((WatchEvent<Path>) watchEvent)
                                .context();
                        // Output
                        System.out.println("New path modified: " + newPath);
                    }
                }

                if (!key.reset()) {
                    break; // loop
                }
            }

        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }

    }

    public static void main(String[] args) throws IOException,
            InterruptedException {
        // Folder we are going to watch
        // Path folder =
        // Paths.get(System.getProperty("C:\\Users\\Isuru\\Downloads"));
        File dir = new File("C:\\Users\\Isuru\\Downloads");
        watchDirectoryPath(dir.toPath());
    }
    }
导入静态java.nio.file.LinkOption.NOFOLLOW\u链接;
导入静态java.nio.file.StandardWatchEventTypes.ENTRY\u创建;
导入静态java.nio.file.StandardWatchEventTypes.OVERFLOW;
导入静态java.nio.file.StandardWatchEventTypes.ENTRY\u DELETE;
导入静态java.nio.file.StandardWatchEventTypes.ENTRY\u MODIFY;
导入java.io.File;
导入java.io.IOException;
导入java.nio.file.FileSystem;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.nio.file.WatchEvent;
导入java.nio.file.WatchEvent.Kind;
导入java.nio.file.WatchKey;
导入java.nio.file.WatchService;
公务舱主值班{
公共静态void watchDirectoryPath(路径路径){
//健全性检查-检查路径是否为文件夹
试一试{
布尔值isFolder=(布尔值)Files.getAttribute(路径,
“基础:isDirectory”,无后续链接);
如果(!isFolder){
抛出新的IllegalArgumentException(“路径:”+Path
+“不是文件夹”);
}
}捕获(ioe异常ioe){
//文件夹不存在
ioe.printStackTrace();
}
System.out.println(“监视路径:+path”);
//我们获取路径的文件系统
FileSystem fs=path.getFileSystem();
//我们使用new try()块创建新的WatchService
try(WatchService=fs.newWatchService()){
//我们注册服务的路径
//我们关注创造事件
注册路径(服务、条目和创建);
注册路径(服务、条目和修改);
注册路径(服务、条目和删除);
//启动无限轮询循环
WatchKey=null;
while(true){
key=service.take();
//出列事件
种类=空;
for(WatchEvent WatchEvent:key.pollEvents()){
//获取事件的类型
kind=watchEvent.kind();
如果(溢出==种类){
continue;//循环
}else if(条目_CREATE==种类){
//创建了一条新路径
路径newPath=((WatchEvent)WatchEvent)
.context();
//输出
System.out.println(“创建的新路径:“+newPath”);
}else if(条目_MODIFY==种类){
//修改
路径newPath=((WatchEvent)WatchEvent)
.context();
//输出
System.out.println(“修改新路径:+newPath”);
}
}
如果(!key.reset()){
中断;//循环
}
}
}捕获(ioe异常ioe){
ioe.printStackTrace();
}捕获(中断异常ie){
即printStackTrace();
}
}
公共静态void main(字符串[]args)引发IOException,
中断异常{
//我们要看的文件夹
//路径文件夹=
//path.get(System.getProperty(“C:\\Users\\Isuru\\Downloads”);
File dir=新文件(“C:\\Users\\Isuru\\Downloads”);
watchDirectoryPath(dir.toPath());
}
}

实际上您订阅的活动不正确。只有最后一个侦听器已注册为条目\删除事件类型

要同时注册所有类型的事件,您应使用:

 path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE); 

警告!无耻的自我推销

我已经围绕Java1.7的
WatchService
创建了一个包装器,它允许注册一个目录和任意数量的glob模式。这个类将负责过滤,并且只发出您感兴趣的事件

DirectoryWatchService watchService = new SimpleDirectoryWatchService(); // May throw
watchService.register( // May throw
        new DirectoryWatchService.OnFileChangeListener() {
            @Override
            public void onFileCreate(String filePath) {
                // File created
            }

            @Override
            public void onFileModify(String filePath) {
                // File modified
            }

            @Override
            public void onFileDelete(String filePath) {
                // File deleted
            }
        },
        <directory>, // Directory to watch
        <file-glob-pattern-1>, // E.g. "*.log"
        <file-glob-pattern-2>, // E.g. "input-?.txt"
        ... // As many patterns as you like
);

watchService.start();
DirectoryWatchService watchService=new SimpleDirectoryWatchService();//可以扔
watchService.register(//可以抛出
新建DirectoryWatchService.OnFileChangeListener(){
@凌驾
公共void onFileCreate(字符串文件路径){
//创建的文件
}
@凌驾
公共void onFileModify(字符串文件路径){
//文件修改
}
@凌驾
公共void onFileDelete(字符串文件路径){
//文件删除
}
},
,//要监视的目录
,//例如“*.log”
,//例如“输入-?.txt”
…//你喜欢多少图案都行
);
watchService.start();

完整的代码在这里。

我为此制作了一些类

public interface FileAvailableListener {
    public void fileAvailable(File file) throws IOException;
}

public类DirectoryWatcher{
私人定时器;
私有列表任务=新建ArrayList();
public DirectoryWatcher()抛出URISyntaxException、IOException、InterruptedException{
超级();
定时器=新定时器(真);
}
public void addDirectoryMonitoringTask(DirectoryMonitorTask任务,长周期){
任务。添加(任务);
timer.scheduleAtFixedRate(任务,5000,周期);
}
公共列表getTasks(){
返回集合。不可修改列表(任务);
}
公共计时器getTimer(){
返回计时器;
}
}

class DirectoryMonitorTask扩展了TimerTask{
公共最终静态字符串目录\u NAME\u ARCHIVE=“ARCHIVE”;
公共最终静态字符串目录\u NAME\u ERROR=“ERROR”;
公共最终静态字符串锁文件扩展名=“.LOCK”;
公共最终静态字符串错误\u文件\u扩展名=“.ERROR”;
公共最终静态字符串文件\u DATE\u FORMAT=“yyyymmddhhmmssss”;
私有字符串名称;
私有文件可用侦听器侦听器;
专用路径目录;
私有的
public class FileChange {

private long lastModified;
private long size;
private long lastCheck;

public FileChange(File file) {
    this.lastModified=file.lastModified();
    this.size=file.length();
    this.lastCheck = System.currentTimeMillis();
}

public long getLastModified() {
    return lastModified;
}
public long getSize() {
    return size;
}
public long getLastCheck() {
    return lastCheck;
}

public boolean isStable(FileChange other,long stableTime) {
    boolean b1 = (getLastModified()==other.getLastModified());
    boolean b2 = (getSize()==other.getSize());
    boolean b3 = ((other.getLastCheck()-getLastCheck())>stableTime);
    return b1 && b2 && b3;
}
}
public class DirectoryWatcher {

private Timer timer;
private List<DirectoryMonitorTask> tasks = new ArrayList<DirectoryMonitorTask>();

public DirectoryWatcher() throws URISyntaxException, IOException, InterruptedException {
    super();
    timer = new Timer(true);        
}
public void addDirectoryMonitoringTask(DirectoryMonitorTask task,long period) {
    tasks.add(task);
    timer.scheduleAtFixedRate(task, 5000, period);      
}
public List<DirectoryMonitorTask> getTasks() {
    return Collections.unmodifiableList(tasks);
}
public Timer getTimer() {
    return timer;
}
}
class DirectoryMonitorTask extends TimerTask {

public final static String DIRECTORY_NAME_ARCHIVE="archive";
public final static String DIRECTORY_NAME_ERROR="error";
public final static String LOCK_FILE_EXTENSION=".lock";
public final static String ERROR_FILE_EXTENSION=".error";   
public final static String FILE_DATE_FORMAT="yyyyMMddHHmmssSSS";

private String name;
private FileAvailableListener listener;
private Path directory;
private File directoryArchive;
private File directoryError;
private long stableTime;
private FileFilter filter;
private WatchService watchService;
private SimpleDateFormat dateFormatter = new SimpleDateFormat(FILE_DATE_FORMAT);
private Hashtable<File,FileChange> fileMonitor = new Hashtable<File,FileChange>();

public DirectoryMonitorTask(String name,FileAvailableListener listener,Path directory,long stableTime,FileFilter filter) throws IOException {
    super();
    this.name=name;
    this.listener=listener;
    this.directory=directory;
    this.stableTime=stableTime;
    if (stableTime<1) {
        stableTime=1000;
    }
    this.filter=filter;
    validateNotNull("Name",name);
    validateNotNull("Listener",listener);
    validateNotNull("Directory",directory);
    validate(directory);
    directoryArchive = new File(directory.toFile(),DIRECTORY_NAME_ARCHIVE);
    directoryError = new File(directory.toFile(),DIRECTORY_NAME_ERROR);
    directoryArchive.mkdir();
    directoryError.mkdir();
    //
    log("Constructed for "+getDirectory().toFile().getAbsolutePath());

    initialize();
    //
    watchService = FileSystems.getDefault().newWatchService();
    directory.register(watchService,StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_DELETE,StandardWatchEventKinds.ENTRY_MODIFY);
    log("Started");
}

private void initialize() {
    File[] files = getDirectory().toFile().listFiles();
    for (File file : files) {
        if (isLockFile(file)) {
            file.delete();
        } else if (acceptFile(file)) {
            fileMonitor.put(file,new FileChange(file));
            log("Init file added -"+file.getName());
        }
    }
}
public SimpleDateFormat getDateFormatter() {
    return dateFormatter;
}
public Path getDirectory() {
    return directory;
}
public FileAvailableListener getListener() {
    return listener;
}
public String getName() {
    return name;
}
public WatchService getWatchService() {
    return watchService;
}
public long getStableTime() {
    return stableTime;
}
public File getDirectoryArchive() {
    return directoryArchive;
}
public File getDirectoryError() {
    return directoryError;
}
public FileFilter getFilter() {
    return filter;
}   
public Iterator<File> getMonitoredFiles() {
    return fileMonitor.keySet().iterator();
}

@Override
public void run() {
    WatchKey key;
    try {
        key = getWatchService().take();
        // Poll all the events queued for the key
        for (WatchEvent<?> event : key.pollEvents()) {                                      
            @SuppressWarnings("unchecked")
            Path filePath = ((WatchEvent<Path>) event).context();
            File file = filePath.toFile();
            if ((!isLockFile(file)) && (acceptFile(file))) {
                switch (event.kind().name()) {
                    case "ENTRY_CREATE":
                        //                          
                        fileMonitor.put(file,new FileChange(file));
                        log("File created ["+file.getName()+"]");
                        break;
                        //
                    case "ENTRY_MODIFY":
                        //                          
                        fileMonitor.put(file,new FileChange(file));
                        log("File modified ["+file.getName()+"]");
                        break;  
                        //
                    case "ENTRY_DELETE":
                        //
                        log("File deleted ["+file.getName()+"]");
                        createLockFile(file).delete();
                        fileMonitor.remove(file);                           
                        break;
                        //
                }
            }
        }
        // reset is invoked to put the key back to ready state
        key.reset();
    } catch (InterruptedException e) {              
        e.printStackTrace();
    }

    Iterator<File> it = fileMonitor.keySet().iterator();

    while (it.hasNext()) {
        File file = it.next();  
        FileChange fileChange = fileMonitor.get(file);
        FileChange fileChangeCurrent = new FileChange(file);

        if (fileChange.isStable(fileChangeCurrent, getStableTime())) {
            log("File is stable ["+file.getName()+"]");
            String filename = getDateFormatter().format(new Date())+"_"+file.getName();
            File lockFile = createLockFile(file);
            if (!lockFile.exists()) {
                log("File do not has lock file ["+file.getName()+"]");
                try {
                    Files.createFile(lockFile.toPath());
                    log("Processing file ["+file.getName()+"]");
                    getListener().fileAvailable(file);                      
                    file.renameTo(new File(getDirectoryArchive(),filename));
                    log("Moved to archive file ["+file.getName()+"]");
                } catch (IOException e) {                       
                    file.renameTo(new File(getDirectoryError(),filename));
                    createErrorFile(file,e);
                    log("Moved to error file ["+file.getName()+"]");
                } finally {
                    lockFile.delete();

                }
            } else {                    
                log("File do has lock file ["+file.getName()+"]");
                fileMonitor.remove(file);
            }               
        } else {                
            log("File is unstable ["+file.getName()+"]");
            fileMonitor.put(file,fileChangeCurrent);
        }
    }       
}

public boolean acceptFile(File file) {
    if (getFilter()!=null) {
        return getFilter().accept(file);
    } else {
        return true;
    }       
}

public boolean isLockFile(File file) {
    int pos = file.getName().lastIndexOf('.');
    String extension="";
    if (pos!=-1) {
        extension = file.getName().substring(pos).trim().toLowerCase();
    }   
    return(extension.equalsIgnoreCase(LOCK_FILE_EXTENSION));
}

private File createLockFile(File file) {
    return new File(file.getParentFile(),file.getName()+LOCK_FILE_EXTENSION);
}

private void createErrorFile(File file,IOException exception) {
    File errorFile = new File(file.getParentFile(),file.getName()+ERROR_FILE_EXTENSION);

    StringWriter sw = null;
    PrintWriter pw = null;
    FileWriter fileWriter = null;
    try {
        //          
        fileWriter = new FileWriter(errorFile);
        if (exception!=null) {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            exception.printStackTrace(pw);      
            fileWriter.write(sw.toString());
        } else {
            fileWriter.write("Exception is null.");
        }
        //      
        fileWriter.flush();
        //
    } catch (IOException e) {
    } finally {
        if (sw!=null) {
            try {
                sw.close();
            } catch (IOException e1) {              
            }
        }
        if (pw!=null) {
            pw.close();
        }
        if (fileWriter!=null) {
            try {
                fileWriter.close();
            } catch (IOException e) {                   
            }
        }
    }
}

private void validateNotNull(String name,Object obj) {
    if (obj==null) {
        throw new NullPointerException(name+" is null.");
    }           
}       
private void validate(Path directory) throws IOException {          
    File file = directory.toFile();
    if (!file.exists()) {
        throw new IOException("Directory ["+file.getAbsolutePath()+"] do not exists.");
    } else if (!file.isDirectory()) {
        throw new IOException("Directory ["+file.getAbsolutePath()+"] is not a directory.");
    } else if (!file.canRead()) {               
        throw new IOException("Can not read from directory ["+file.getAbsolutePath()+"].");
    } else if (!file.canWrite()) {
        throw new IOException("Can not write to directory ["+file.getAbsolutePath()+"] .");
    }       
}

private void log(String msg) {
    //TODO
    System.out.println("Task ["+getName()+"] "+msg);
}
}
package p1;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.LinkOption.NOFOLLOW_LINKS;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.List;

public class WatchForFile {

    public void WatchMyFolder(String path )
    {
        File dir = new File(path);
        Path myDir= dir.toPath();
          try 
          {
              Boolean isFolder = (Boolean) Files.getAttribute(myDir,"basic:isDirectory", NOFOLLOW_LINKS);
              if (!isFolder)
              {
                  throw new IllegalArgumentException("Path: " + myDir + " is not a folder");
              }
          }
          catch (IOException ioe)
          {
              ioe.printStackTrace();
          }

          System.out.println("Watching path: " + myDir);

        try {
           WatchService watcher = myDir.getFileSystem().newWatchService();
           myDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);

           WatchKey watckKey = watcher.take();

           List<WatchEvent<?>> events = watckKey.pollEvents();

           for (WatchEvent event : events) {
                if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
                    System.out.println("Created: " + event.kind().toString());

                }
                if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
                    System.out.println("Delete: " + event.context().toString());
                }
                if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
                    System.out.println("Modify: " + event.context().toString());
                }
            }

        }
        catch (Exception e) 
        {
            System.out.println("Error: " + e.toString());
        }
    }
}
Path path = Paths.get("/home/omkar/test");
public class FileHandlerTest implements FileHandler {

    private static final Logger LOGGER = Logger.getLogger(FileHandlerTest.class.getName());

    /*
     * This implemented method will delete the file
     * 
     * @see com.io.util.FileHandler#handle(java.io.File,
     * java.nio.file.WatchEvent.Kind)
     */
    public void handle(File file, Kind<?> fileEvent) {
        LOGGER.log(Level.INFO,"Handler is triggered for file {0}",file.getPath());
        if(fileEvent == StandardWatchEventKinds.ENTRY_CREATE) {
            try {
                boolean deleted = Files.deleteIfExists(Paths.get(file.getPath()));
                assertTrue(deleted);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
FileHandlerTest fileHandlerTest = new FileHandlerTest();
FileWatcher fileWatcher = new FileWatcher(path, fileHandlerTest, StandardWatchEventKinds.ENTRY_CREATE);
Thread watcherThread = new Thread(fileWatcher);
watcherThread.start();
public class FileWatcher implements Runnable {

private static final Logger LOGGER =Logger.getLogger(FileWatcher.class.getName());

private WatchService watcher;
private FileHandler fileHandler;
private List<Kind<?>> watchedEvents;
private Path directoryWatched;

/**
 * @param directory
 * @Path directory to watch files into
 * @param fileHandler
 * @FileHandler implemented instance to handle the file event
 * @param watchRecursive
 *            if directory is to be watched recursively
 * @param watchedEvents
 *            Set of file events watched
 * 
 * @throws IOException
 */
public FileWatcher(Path directory, FileHandler fileHandler, boolean watchRecursive,
        WatchEvent.Kind<?>... watchedEvents) throws IOException {
    super();
    this.watcher = FileSystems.getDefault().newWatchService();
    this.fileHandler = fileHandler;
    this.directoryWatched = directory;
    this.watchedEvents = Arrays.asList(watchedEvents);
    if (watchRecursive) {
        // register all subfolders
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                LOGGER.log(Level.INFO, "Registering {0} ", dir);
                dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE,
                        StandardWatchEventKinds.ENTRY_MODIFY);
                return FileVisitResult.CONTINUE;
            }
        });
    } else {
        directory.register(watcher, watchedEvents);
    }
}

@SuppressWarnings({ "unchecked" })
public void run() {
    LOGGER.log(Level.INFO, "Starting FileWatcher for {0}", directoryWatched.toAbsolutePath());
    WatchKey key = null;
    while (true) {
        try {
            key = watcher.take();
            if (key != null) {
                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();

                    WatchEvent<Path> ev = (WatchEvent<Path>) event;
                    //directory in which file event is detected
                    Path directory = (Path) key.watchable(); 
                    Path fileName = ev.context();
                    if (watchedEvents.contains(kind)) {
                        LOGGER.log(Level.INFO, "Invoking handle on {0}", fileName.toAbsolutePath());
                        fileHandler.handle(directory.resolve(fileName).toFile(), kind);
                    }
                }
                key.reset();
            }
        } catch (InterruptedException ex) {
            LOGGER.log(Level.SEVERE, "Polling Thread was interrupted ", ex);
            Thread.currentThread().interrupt();
        }
    }
}