歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java監控文件變化

Java監控文件變化

日期:2017/3/1 10:15:20   编辑:Linux編程

問題:
存在兩個文件目錄,且稱之為源目錄和目標目錄,需要不定期將源目錄和目標目錄進行同步。
兩種同步方法:
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. import net.contentobjects.jnotify.JNotify;
  3. import net.contentobjects.jnotify.JNotifyListener;
  4. public class FileWatch
  5. {
  6. public static void main(String[] args)
  7. {
  8. try
  9. {
  10. new FileWatch().sampleTest();
  11. }
  12. catch (Exception e)
  13. {
  14. e.printStackTrace();
  15. }
  16. }
  17. public void sampleTest() throws Exception
  18. {
  19. // path to watch
  20. String path = "D:\\download";
  21. // watch mask, specify events you care about,
  22. // or JNotify.FILE_ANY for all events.
  23. int mask = JNotify.FILE_CREATED
  24. | JNotify.FILE_DELETED
  25. | JNotify.FILE_MODIFIED
  26. | JNotify.FILE_RENAMED;
  27. // watch subtree?
  28. boolean watchSubtree = true;
  29. // add actual watch
  30. int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());
  31. // sleep a little, the application will exit if you
  32. // don't (watching is asynchronous), depending on your
  33. // application, this may not be required
  34. Thread.sleep(1000000);
  35. // to remove watch the watch
  36. boolean res = JNotify.removeWatch(watchID);
  37. if (!res)
  38. {
  39. // invalid watch ID specified.
  40. }
  41. }
  42. class Listener implements JNotifyListener
  43. {
  44. public void fileRenamed(int wd, String rootPath, String oldName, String newName)
  45. {
  46. print("renamed " + rootPath + " : " + oldName + " -> " + newName);
  47. }
  48. public void fileModified(int wd, String rootPath, String name)
  49. {
  50. print("modified " + rootPath + " : " + name);
  51. }
  52. public void fileDeleted(int wd, String rootPath, String name)
  53. {
  54. print("deleted " + rootPath + " : " + name);
  55. }
  56. public void fileCreated(int wd, String rootPath, String name)
  57. {
  58. print("created " + rootPath + " : " + name);
  59. }
  60. void print(String msg)
  61. {
  62. System.err.println(msg);
  63. }
  64. }
  65. }
Copyright © Linux教程網 All Rights Reserved