简体   繁体   中英

java program to monitor a directory

I want to create a program that monitor a directory 24/7 and if a new file is added to it then it should sort it if the file is greater then 10mb. I have implemented the code for my directory but I don't know how to make it check the directory every time a new record is added as it has to happen in continuous manner.

import java.io.*;
import java.util.Date;

public class FindingFiles {

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

        File dir = new File("C:\\Users\\Mayank\\Desktop\\java princeton");// Directory that contain the files to be searched 
        File[] files= dir.listFiles();
        File des=new File("C:\\Users\\Mayank\\Desktop\\newDir");  // new directory where files are to be moved 
        
        if(!des.exists())
        des.mkdir();
        
        for(File f : files ){
            long diff = new Date().getTime() - f.lastModified();
            
            if( (f.length() >= 10485760) || (diff > 10 * 24 * 60 * 60 * 1000) )
            {
                f.renameTo(new File("C:\\Users\\mayank\\Desktop\\newDir\\"+f.getName()));
          
            }  }  
}
}

The watch Service should match to your need : https://docs.oracle.com/javase/tutorial/essential/io/notification.html

Here are the basic steps required to implement a watch service:

  • Create a WatchService "watcher" for the file system.
  • For each directory that you want monitored, register it with the watcher. When registering a directory, you specify the type of events for which you want notification. You receive a WatchKey instance for each directory that you register.
  • Implement an infinite loop to wait for incoming events. When an event occurs, the key is signaled and placed into the watcher's queue. Retrieve the key from the watcher's queue. You can obtain the file name from the key.
  • Retrieve each pending event for the key (there might be multiple events) and process as needed.
  • Reset the key, and resume waiting for events.
  • Close the service: The watch service exits when either the thread exits or when it is closed (by invoking its closed method).

As a side note, you should favor the java.nio package available since Java 7 to move files.

The renameTo() has some serious limitations (extracted from the Javadoc) :

Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.

For example on Windows, renameTo() may fail if the target directory exists, even if it's empty.
Besides the method may return a boolean when it fails instead of an exception.
In this way it may be hard to guess the origin of the problem and to handle it in the code.

Here is a simple class that performs your requirement (it handles all steps but the Watch Service closing that is not necessarily required).

package watch;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class WatchDir {

    private final WatchService watcher;
    private final Map<WatchKey, Path> keys;

    private Path targetDirPath;
    private Path sourceDirPath;

    WatchDir(File sourceDir, File targetDir) throws IOException {
        this.watcher = FileSystems.getDefault().newWatchService();
        this.keys = new HashMap<WatchKey, Path>();
        this.sourceDirPath = Paths.get(sourceDir.toURI());
        this.targetDirPath = Paths.get(targetDir.toURI());

        WatchKey key = sourceDirPath.register(watcher, ENTRY_CREATE);
        keys.put(key, sourceDirPath);
    }

    public static void main(String[] args) throws IOException {
        // Directory that contain the files to be searched
        File dir = new File("C:\\Users\\Mayank\\Desktop\\java princeton");

        // new directory where files are to be moved
        File des = new File("C:\\Users\\Mayank\\Desktop\\newDir");

        if (!des.exists())
            des.mkdir();

        // register directory and process its events
        new WatchDir(dir, des).processEvents();
    }


    /**
     * Process all events for keys queued to the watcher
     * 
     * @throws IOException
     */
    private void processEvents() throws IOException {
        for (;;) {

            // wait for key to be signalled
            WatchKey key;
            try {
                key = watcher.take();
            } catch (InterruptedException x) {
                return;
            }

            Path dir = keys.get(key);
            if (dir == null) {
                System.err.println("WatchKey not recognized!!");
                continue;
            }

            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();

                // Context for directory entry event is the file name of entry
                @SuppressWarnings("unchecked")
                WatchEvent<Path> ev = (WatchEvent<Path>) event;
                Path name = ev.context();
                Path child = dir.resolve(name);

                // print out event
                System.out.format("%s: %s\n", event.kind().name(), child);

                // here is a file or a folder modified in the folder
                File fileCaught = child.toFile();

                // here you can invoke the code that performs the test on the
                // size file and that makes the file move
                long diff = new Date().getTime() - fileCaught.lastModified();

                if (fileCaught.length() >= 10485760 || diff > 10 * 24 * 60 * 60 * 1000) {
                    System.out.println("rename done for " + fileCaught.getName());
                    Path sourceFilePath = Paths.get(fileCaught.toURI());
                    Path targetFilePath = targetDirPath.resolve(fileCaught.getName());
                    Files.move(sourceFilePath, targetFilePath);
                }
            }

            // reset key and remove from set if directory no longer accessible
            boolean valid = key.reset();
            if (!valid) {
                keys.remove(key);

                // all directories are inaccessible
                if (keys.isEmpty()) {
                    break;
                }
            }
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM