1

I wrote a Java program which watches a directory for changes. I keep a list of files (String[]) and at every x seconds I get a new list and compare them to find which files were added and which ones were removed.

The problem is that if I rename a file, it would appear as a removal of a file with the old name and then as an addition of a file with the new name.

What could I do to keep track of name changes?

EDIT: I would like to find a solution for Java 6. Code:

public void run() {
    int ok;
    while(true) {
        // verify if modified from last check
        if(modified != file.lastModified()) {
            Date d = new Date();
            list = file.list();
            // look for new files
            for(String x : list) {
                ok = 0;
                for(String y : old) {
                    if(x.equals(y)) {
                        ok = 1;
                    }
                }
                if(ok == 0) {  
                    display.setText(display.getText() + "Created file " + x  + " at " + d.toString() + "\n");
                }
            }
            // looking for old files
            for(String x : old) {
                ok = 0;
                for(String y : list) {
                    if(x.equals(y)) {
                        ok = 1;
                    }
                }
                if(ok == 0) {
                    display.setText(display.getText() + "Deleted file " + x + " at " + d.toString() + "\n");
                }
            }
        }
        old = file.list();
        modified = file.lastModified();
        try {
            Thread.sleep(f * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Also, in this code, if I want to write old = list (to keep the last list), i get a NullPointerException at line for(String y : old). Why?

Sorin
  • 908
  • 2
  • 8
  • 19
  • Do you have code to share, so we know how you're currently accomplishing this? – Eric Wich Jun 12 '13 at 16:02
  • are you based on name of the files? instead of name, may be you can use id sort of thing in file system... in that way even if a file is rename it's id is not changed..... http://stackoverflow.com/questions/8289598/file-id-for-keeping-track-of-file-changes-in-java – pinkpanther Jun 12 '13 at 16:04
  • 1
    Depending on the ammount of files you could make the CRC o MD5 of the files and keep checking against these hashes so you will know for sure if a file is deleted or not. – Averroes Jun 12 '13 at 16:12

1 Answers1

1

I don't think there is a way to do this that is both portable, reliable and efficient.

  • Reading the file content is expensive and can be unreliable. (For instance, it will break if you have two files with the same content.

  • Relying on file timestamps can be unreliable. (You could have different files with the same timestamps.)

  • I don't think that a WatchService can detect files that are renamed within a directory. (It can detect a rename in or rename out, but not this case ... according to this javadoc.)

  • The reliable and efficient way to do it (on Linux systems at least) is to either use the native Linux watch service (which supports more FS events), or a combination of the inode numbers and the native file creation timestamp. But these both involve using native code to make the relevant system calls.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216