歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java監控文件變化

問題:
存在兩個文件目錄,且稱之為源目錄和目標目錄,需要不定期將源目錄和目標目錄進行同步。
兩種同步方法:
1 采用從源目錄到目標目錄的完全拷貝覆蓋。顯而易見的缺點,當文件目錄中文件多、體積大時拷貝過程時間消耗極大。
2 采用從源目錄到目標目錄的變更集拷貝覆蓋。避免了大量拷貝的IO耗時操作,但產生了新的問題:如何獲取變更信息?

新問題:
如何監控一個文件目錄的變更情況。
還是兩種方法:
1 掃描式。不定期對源目錄進行輪循掃描,獲取變更。弱點:同樣的,文件目錄中文件多、體積大時掃描耗時久,響應也慢。
2 事件驅動式。當源目錄發生變更時,拋出變更事件。JNI和JNotify可以提供支持,據說JDK 7內置支持,不過咱公司還沒用上。

JNotify相關介紹:
JNotify:http://jnotify.sourceforge.net/,通過JNI技術,讓Java代碼可以實時的監控制定文件夾內文件的變動信息,支持Linux/Windows/MacOS。

JNotify的准備:
在使用JNotify之前,你需要“安裝”一下JNotify,分為兩個部分:jnotify-lib-0.93.jar和jnotify.dll/jnotify_64bit.dll。
jar自然設計類路徑即可,dll則放置在java.library.path所指向的文件夾中。

java.library.path的值可以在java程序中通過如下語句:
System.getProperty("java.library.path")
查看,一般在windows下放在[jre安裝目錄]/bin下即可;
也可以手動指定程序的啟動參數:
java -Djava.library.path=[dll路徑]
的方法來達到目的;
也可以在java程序中通過如下語句:
System.load("xxxx/jnotify.dll")
來加載dll,這個可以方便程序打包。

JNotify使用了JNI技術來調用系統的本地庫(Win下的是dll文件,Linux下是so文件),dll放置不正確,會有如下報錯:
java.lang.UnsatisfiedLinkError: no jnotify in java.library.path 
    at java.lang.ClassLoader.loadLibrary(Unknown Source) 
    at java.lang.Runtime.loadLibrary0(Unknown Source) 
    at java.lang.System.loadLibrary(Unknown Source) 
    at net.contentobjects.jnotify.win32.JNotify_win32.<clinit>(Unknown Source) 
    at net.contentobjects.jnotify.win32.JNotifyAdapterWin32.<init>(Unknown Source) 

JNotify使用示例:

  1. package com.dancen.test;  
  2.   
  3.   
  4. import net.contentobjects.jnotify.JNotify;  
  5. import net.contentobjects.jnotify.JNotifyListener;  
  6.   
  7.   
  8. public class FileWatch   
  9. {  
  10.     public static void main(String[] args)  
  11.     {  
  12.         try  
  13.         {  
  14.             new FileWatch().sampleTest();  
  15.         }  
  16.         catch (Exception e)  
  17.         {  
  18.             e.printStackTrace();  
  19.         }  
  20.     }  
  21.       
  22.     public void sampleTest() throws Exception  
  23.     {  
  24.         // path to watch   
  25.         String path = "D:\\download";  
  26.   
  27.   
  28.         // watch mask, specify events you care about,   
  29.         // or JNotify.FILE_ANY for all events.   
  30.         int mask = JNotify.FILE_CREATED  
  31.                 | JNotify.FILE_DELETED  
  32.                 | JNotify.FILE_MODIFIED  
  33.                 | JNotify.FILE_RENAMED;  
  34.   
  35.   
  36.         // watch subtree?   
  37.         boolean watchSubtree = true;  
  38.   
  39.   
  40.         // add actual watch   
  41.         int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());  
  42.   
  43.   
  44.         // sleep a little, the application will exit if you   
  45.         // don't (watching is asynchronous), depending on your   
  46.         // application, this may not be required   
  47.         Thread.sleep(1000000);  
  48.   
  49.   
  50.         // to remove watch the watch   
  51.         boolean res = JNotify.removeWatch(watchID);  
  52.           
  53.         if (!res)  
  54.         {  
  55.             // invalid watch ID specified.   
  56.         }  
  57.     }  
  58.   
  59.   
  60.     class Listener implements JNotifyListener   
  61.     {  
  62.         public void fileRenamed(int wd, String rootPath, String oldName, String newName)   
  63.         {  
  64.             print("renamed " + rootPath + " : " + oldName + " -> " + newName);  
  65.         }  
  66.   
  67.   
  68.         public void fileModified(int wd, String rootPath, String name)  
  69.         {  
  70.             print("modified " + rootPath + " : " + name);  
  71.         }  
  72.   
  73.   
  74.         public void fileDeleted(int wd, String rootPath, String name)  
  75.         {  
  76.             print("deleted " + rootPath + " : " + name);  
  77.         }  
  78.   
  79.   
  80.         public void fileCreated(int wd, String rootPath, String name)  
  81.         {  
  82.             print("created " + rootPath + " : " + name);  
  83.         }  
  84.   
  85.   
  86.         void print(String msg)   
  87.         {  
  88.             System.err.println(msg);  
  89.         }  
  90.     }  
  91. }  
Copyright © Linux教程網 All Rights Reserved