posts - 59, comments - 244, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

java实现文件监控

Posted on 2011-01-09 16:32 penngo 阅读(14500) 评论(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.blogjava.net/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
怎么在追加信息里加入时间

只有注册用户登录后才能发表评论。


网站导航: