java实现文件监控

转载自:http://www.oschina.net/code/snippet_70229_2994

java本身不能直接监听系统的文件操作事件,不过可以先编写C/C++调用操作系统的API监听文件,再通过jni调用的方式实现。限于本人的C/C++水平有限,没有用C/C++实现该接口,而且已有开源组件JNotify实现了这个功能,本文例子使用JNotify。

package org.bruce.toolkit.experiments;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class MainFrame extends JFrame {
	private static final long serialVersionUID = 5707722022801012830L;
	
	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(100, 100, 543, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel label = new JLabel("监控路径:");
        label.setBounds(33, 20, 65, 15);
        contentPane.add(label);

        textField = new JTextField("D:/");
        textField.setBounds(90, 16, 219, 21);
        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(319, 16, 93, 23);
        contentPane.add(button);

        textArea = new JTextArea();
        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setBounds(33, 45, 480, 207);
        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");
        }
    }
}
JNotify主页: http://jnotify.sourceforge.net/macos.html

JNotify release note for MacOS:

Because of the way Mac OS X handles file change notifications, some things may work differently. 

If you are concerned about Mac support, you should be aware of the following:
Events are not guaranteed to be reported in order.

 Events should be reported within two seconds of occuring. 

Multiple events occuring within two seconds may be reported in any order.
File changes that are present less than two seconds may be missed. 

For example, mv a b && mv b c may report only a single rename.
The code that detects renames is only aware of files being watched. 

If a file outside the watched directory is moved into the directory, it will be reported as a create.

 Likewise, if a file is moved out of the watched directory, it will be reported as a delete.


The Mac OS X API for file system events only reports what directory 

changes have occured in, and has some latency in it. If you register a net.contentobjects.

jnotify.macosx.FSEventListener with net.contentobjects.jnotify.macosx.JNotify_macosx, 

you'll receive a notifyChange event telling you when a directory has changed, 

within a second of the change occuring. 

The OS will merge changes together so you'll only get one notification per

 directory within one second, regardless of how many changes have occured. 

If too many changes occur in different subdirectories, the OS may merge 

them into a single event for a common parent directory, in which case the 

recurse flag will be set. See the FSEvents API for more details.


你可能感兴趣的:(java,exception,String,button,events,notifications)