posts - 59, comments - 244, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          java實現文件監控

          Posted on 2011-01-09 16:32 penngo 閱讀(14526) 評論(10)  編輯  收藏 所屬分類: Java

          java本身不能直接監聽系統的文件操作事件,不過可以先編寫C/C++調用操作系統的API監聽文件,再通過jni調用的方式實現。限于本人的C/C++水平有限,沒有用C/C++實現該接口,而且已有開源組件JNotify實現了這個功能,本文例子使用JNotify。

          public class MainFrame extends JFrame {

              
          private JPanel contentPane;
              
          private JTextField textField;
              
          private JTextArea textArea;

              
          public static void main(String[] args) {
                  EventQueue.invokeLater(
          new Runnable() {
                      
          public void run() {
                          
          try {
                              MainFrame frame 
          = new MainFrame();
                              frame.setVisible(
          true);
                          } 
          catch (Exception e) {
                              e.printStackTrace();
                          }
                      }
                  });
              }

              
          public MainFrame() {
                  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  setBounds(
          100100543300);
                  contentPane 
          = new JPanel();
                  contentPane.setBorder(
          new EmptyBorder(5555));
                  setContentPane(contentPane);
                  contentPane.setLayout(
          null);

                  JLabel label 
          = new JLabel("監控路徑:");
                  label.setBounds(
          33206515);
                  contentPane.add(label);

                  textField 
          = new JTextField("D:/");
                  textField.setBounds(
          901621921);
                  contentPane.add(textField);
                  textField.setColumns(
          10);

                  JButton button 
          = new JButton("開始監控");
                  button.addActionListener(
          new ActionListener() {
                      
          public void actionPerformed(ActionEvent e) {
                          
          try {
                              addWatch();
                          } 
          catch (Exception ex) {
                              ex.printStackTrace();
                          }
                      }
                  });
                  button.setBounds(
          319169323);
                  contentPane.add(button);

                  textArea 
          = new JTextArea();
                  JScrollPane scrollPane 
          = new JScrollPane(textArea);
                  scrollPane.setBounds(
          3345480207);
                  contentPane.add(scrollPane);
              }

              
          public void addWatch() throws Exception {
                  String path 
          = textField.getText();
                  
          int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED
                          
          | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
                  
          boolean watchSubtree = true;
                  
          //添加文件監聽
                  int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());
              }

              
          class Listener implements JNotifyListener {
                  
          public void fileRenamed(int wd, String rootPath, String oldName,
                          String newName) {
                      textArea.append(
          "文件:" + rootPath + " : " + oldName + " 重命名為: "
                              
          + newName + "\n");
                  }

                  
          public void fileModified(int wd, String rootPath, String name) {
                      textArea.append(
          "文件修改 " + rootPath + " : " + name + "\n");
                  }

                  
          public void fileDeleted(int wd, String rootPath, String name) {
                      textArea.append(
          "刪除文件: " + rootPath + " : " + name + "\n");
                  }

                  
          public void fileCreated(int wd, String rootPath, String name) {
                      textArea.append(
          "新建文件: " + rootPath + " : " + name + "\n");
                  }
              }
          }

          運行效果:
          在D盤新建一個文件和修改文件名操作。
          http://www.aygfsteel.com/pengo

          附件:源碼

          評論

          # re: java實現文件監控[未登錄]  回復  更多評論   

          2011-01-10 23:35 by semmy
          無法監控到打開文件和文件夾,只能監控到增、刪、改。

          # re: java實現文件監控[未登錄]  回復  更多評論   

          2011-01-10 23:40 by semmy
          不知道有沒有辦法監控到打開文件

          # re: java實現文件監控  回復  更多評論   

          2011-01-11 00:32 by pengo
          JNotify現在的版本是沒有監控打開文件,如果你用的是window系統,可以查下window api,看看有監控文件打開的API,有的話用C/C++寫好編譯成DLL,再用通過java的jni或jna調用就行了。

          # re: java實現文件監控  回復  更多評論   

          2011-01-13 11:16 by nihao
          我在使用JNotify的時候發現
          創建一個文件會同時觸發一個Create事件和3-4個Modify事件
          重命名一個文件的時候也同時出發一個Rename事件和一個Modify事件
          修改一個文件的時候會觸發3-4個Modify事件
          我的MASK是
          JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_RENAMED| JNotify.FILE_MODIFIED

          不知道博主是否有遇到過這種問題,謝謝

          # re: java實現文件監控  回復  更多評論   

          2011-01-13 11:18 by nihao
          順便也把我的源代碼貼出來吧:

          package notify;

          import net.contentobjects.jnotify.*;

          class Listener implements JNotifyListener{
          public void fileRenamed(int wd, String rootPath, String oldName, String newName){
          System.out.println("renamed " + rootPath + " : " + oldName + " -> " + newName);
          }
          public void fileModified(int wd, String rootPath, String name){
          System.out.println("modified " + rootPath + " : " + name);
          }
          public void fileDeleted(int wd, String rootPath, String name){
          System.out.println("deleted " + rootPath + " : " + name);
          }
          public void fileCreated(int wd, String rootPath, String name){
          System.out.println("created " + rootPath + " : " + name);
          }
          public void print(String msg){
          System.err.println(msg);
          }
          }

          public class Main {

          public static void main(String[] args) throws JNotifyException {
          // TODO code application logic here
          String path = "D:/test";
          int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_RENAMED
          | JNotify.FILE_MODIFIED
          ;
          boolean watchSubtree = true;
          int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());
          try {
          Thread.sleep(1000000);
          } catch (InterruptedException e1) {
          }
          JNotify.removeWatch(watchID);
          }
          }

          # re: java實現文件監控  回復  更多評論   

          2011-01-13 23:19 by pengo
          創建的時候不會,重命名和修改好像是一樣。

          # re: java實現文件監控  回復  更多評論   

          2012-09-11 16:15 by wzp
          @semmy
          (只試過linux下的,windows下也差不多應該)
          可以添加打開文件的監聽
          在源碼中的JNotifyListener接口中添加open(),然后在JNotifyAdapterLinux(windows的改JNotifyAdapterWin32)類中,添加實現
          由于源碼中已經存在 IN_OPEN = 0x00000020; /* File was opened */的定義,所以可以直接調用它,這個就是linux的打開事件。
          代碼如下:
          在public int addWatch(String path, int mask, boolean watchSubtree, JNotifyListener listener)中添加:
          //訪問文件
          if ((mask & JNotify.FILE_OPENED) != 0)
          {
          linuxMask |= JNotify_linux.IN_OPEN;
          }

          在protected void notifyChangeEvent(String name, int linuxWd, int linuxMask, int cookie)中添加 (具體位置自己讀代碼,應該很容易分析出來的)
          //文件訪問
          else
          if ((linuxMask & JNotify_linux.IN_OPEN) != 0)
          {
          watchData.notifyFileOpened(name);
          }
          最后在下面添加方法
          public void notifyFileOpened(String name)
          {
          String outRoot = getOutRoot();
          String outName = getOutName(name);
          _listener.fileOpenfied(getParentWatchID(), outRoot, outName);
          }
          這個只是linux中的測試代碼,仍然存在很多問題。

          # re: java實現文件監控  回復  更多評論   

          2015-06-29 10:02 by xugy
          @nihao
          你應該是循環中進行了多次 JNotify.addWatch 吧?
          在循環結束前 JNotify.removeWatch(watchID); 應該就好了!

          # re: java實現文件監控  回復  更多評論   

          2016-04-26 19:47 by summer_seo
          怎么在最后追加時間呢

          # re: java實現文件監控  回復  更多評論   

          2016-04-26 19:48 by summer_seo
          怎么在追加信息里加入時間
          主站蜘蛛池模板: 洮南市| 修文县| 怀安县| 盘山县| 淳化县| 陈巴尔虎旗| 桂平市| 湖南省| 钦州市| 株洲市| 孙吴县| 万全县| 固安县| 贞丰县| 阿城市| 连南| 望城县| 临西县| 自治县| 门源| 株洲县| 邮箱| 舒城县| 鄯善县| 梧州市| 周至县| 滦南县| 卢湾区| 远安县| 九龙坡区| 芷江| 宁晋县| 灵武市| 镇康县| 盐亭县| 成都市| 洪泽县| 杭州市| 扎兰屯市| 韩城市| 镇远县|