JNotify

JNotify

Nativ megoldás. Az operációs rendszer értesít a változásokról.

A websiton található sample minimális átirat.

 1public class JNotifySample {
 2  public static void main(String args[]) throws Exception {
 3    // path to watch
 4    String path ="c:/TEMP";
 5    // watch mask, specify events you care about,
 6    // or JNotify.FILE_ANY for all events.
 7    int mask = JNotify.FILE_CREATED |
 8        JNotify.FILE_DELETED |
 9        JNotify.FILE_MODIFIED |
10        JNotify.FILE_RENAMED;
11
12    // watch subtree?
13    boolean watchSubtree = true;
14
15    // add actual watch
16    int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());
17
18    // sleep a little, the application will exit if you
19    // don't (watching is asynchronous), depending on your
20    // application, this may not be required
21    Thread.sleep(1000000);
22
23    // to remove watch the watch
24    boolean res = JNotify.removeWatch(watchID);
25    if (!res) {
26      // invalid watch ID specified.
27    }
28  }
29
30  static class Listener implements JNotifyListener {
31    public void fileRenamed(int wd, String rootPath, String oldName,
32        String newName) {
33      print("renamed " + rootPath + " : " + oldName + " -> " + newName);
34    }
35
36    public void fileModified(int wd, String rootPath, String name) {
37      print("modified " + rootPath + " : " + name);
38    }
39
40    public void fileDeleted(int wd, String rootPath, String name) {
41      print("deleted " + rootPath + " : " + name);
42    }
43
44    public void fileCreated(int wd, String rootPath, String name) {
45      print("created " + rootPath + " : " + name);
46    }
47
48    void print(String msg) {
49      System.err.println(msg);
50    }
51  }
52}

Működésének jellemzői:

Elég körülményes egy buildelő rendszert ráépíteni, mert a file módosításon kívül igen komplex értesítéseket kapunk. Amire lehet egy kicsit építeni az az, hogy bármi is történik vagy a file vagy egy könyvtár módosul. A gond az, hogy többször is. Ha több fájlról van szó, akkor meg állományonként, ami igen nagy.

Igen részletesen lehet az fájlrendszer értesítéseit elkapni, de pont emiatt nagyon nehéz egy olyan egyszerű funkcionalitást is ráépíteni mint az én kis dokumentum fordításom.

A probléma megoldása lehet az, hogy ha értesülünk az eseményről:

  1. lekapcsolódunk az eseményekről egy kicsit, elvégre már az első esemény is elegendő.
  2. Várunk egy kicsit, hogy a folyamatban lévő műveletek be tudjanak fejeződni.
  3. Visszaállunk figyelésre. A végrehajtandó tevékenység lehet, hogy annyi ideig tart, hogy közben teljesen valid másik file esemény megtörténte is.
  4. Végrehajtjuk amit akarunk.

A triggerelt esemény végrehajtásának hosszától függően a 3. és 4. esemény fel is cserélhető.

Konkrétan:

Csupaszítsuk le egy kicsit az alapprogramot:

 1public class JNotifySample2 {
 2  public static void main(String args[]) throws Exception {
 3    String path = "c:/TEMP/notify";
 4    int mask = JNotify.FILE_CREATED |
 5        JNotify.FILE_DELETED |
 6        JNotify.FILE_MODIFIED |
 7        JNotify.FILE_RENAMED;
 8    boolean watchSubtree = false;
 9    JNotify.addWatch(path, mask, watchSubtree, new JNotifyExecutorListener());
10    System.out.println("Press CTR+C to stop...");
11    for (; true;) {
12      Thread.sleep(10000);
13    }
14  }
15}

És a listenert is készítsük el:

 1package public class JNotifyExecutorListener extends JNotifyAdapter {
 2  volatile boolean executing = false;
 3  static void  p(String s){
 4    System.out.println(s);
 5  }
 6  @Override
 7  public void fileModified(int wd, String rootPath, String name) {
 8    p("modification is notified");
 9    if(!name.endsWith(".txt")){
10      return;
11    }
12    p("executing something? "+executing);
13    if (!executing) {
14      p("start the BatchExecutor thread");
15      Thread t = new Thread(new BatchExecutor());
16      t.start();
17    }
18    p("modification handler method end");
19  }
20
21  class BatchExecutor implements Runnable {
22    @Override
23    public void run() {
24      p("setting to execution...");
25      // Indicating that it make no sense to
26      executing = true;
27      p("executing something (BatchExecutor)? "+executing);
28      try {
29        p("sleep a bit...");
30        Thread.sleep(1 * 1000); // 1 sec
31      }
32      catch (InterruptedException e) {
33        p(e.toString());
34        return;
35      }
36      finally {
37        p("setting back flag");
38        // ready to catch the next event
39        executing = false;
40      }
41      p("executing something (BatchExecutor 2)? "+executing);
42
43      try {
44        p("Start command line...");
45        Runtime.getRuntime().exec("cmd /c Path_to/build.bat ");
46      }
47      catch (IOException e) {
48        e.printStackTrace();
49      }
50      p("command is ready");
51    }
52  }
53}

Directory Watcher
Apr 16, 2012
comments powered by Disqus

Links

Cool

RSS