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使用示例:

package com.dancen.test;


import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyListener;


public class FileWatch 
{
	public static void main(String[] args)
	{
		try
		{
			new FileWatch().sampleTest();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void sampleTest() throws Exception
	{
		// path to watch
		String path = "D:\\download";


		// watch mask, specify events you care about,
		// or JNotify.FILE_ANY for all events.
		int mask = JNotify.FILE_CREATED
				| JNotify.FILE_DELETED
				| JNotify.FILE_MODIFIED
				| JNotify.FILE_RENAMED;


		// watch subtree?
		boolean watchSubtree = true;


		// add actual watch
		int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());


		// sleep a little, the application will exit if you
		// don't (watching is asynchronous), depending on your
		// application, this may not be required
		Thread.sleep(1000000);


		// to remove watch the watch
		boolean res = JNotify.removeWatch(watchID);
		
		if (!res)
		{
			// invalid watch ID specified.
		}
	}


	class Listener implements JNotifyListener 
	{
		public void fileRenamed(int wd, String rootPath, String oldName, String newName) 
		{
			print("renamed " + rootPath + " : " + oldName + " -> " + newName);
		}


		public void fileModified(int wd, String rootPath, String name)
		{
			print("modified " + rootPath + " : " + name);
		}


		public void fileDeleted(int wd, String rootPath, String name)
		{
			print("deleted " + rootPath + " : " + name);
		}


		public void fileCreated(int wd, String rootPath, String name)
		{
			print("created " + rootPath + " : " + name);
		}


		void print(String msg) 
		{
			System.err.println(msg);
		}
	}
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
你可以使用JavaWatchService来监控文件夹中新增的文件WatchService是Java NIO 2中的一个特性,它可以监控文件系统的变化,如文件的创建、修改和删除等。 以下是一个简单的示例代码,用于监控指定文件夹中新增的文件: ```java import java.nio.file.*; public class FolderWatcher { public static void main(String[] args) throws Exception { // 获取文件监控服务 WatchService watchService = FileSystems.getDefault().newWatchService(); // 注册要监控文件夹,并设置监控类型为新增文件 Path folderPath = Paths.get("/path/to/folder"); folderPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE); // 循环获取文件变化事件 while (true) { WatchKey watchKey = watchService.take(); // 遍历所有文件变化事件 for (WatchEvent<?> event : watchKey.pollEvents()) { // 判断事件类型是否为新增文件 if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) { // 获取新增文件的路径 Path filePath = folderPath.resolve((Path) event.context()); System.out.println("New file created: " + filePath); } } // 重置监控,以便下次继续监控 watchKey.reset(); } } } ``` 在上面的示例代码中,我们首先获取了文件监控服务,并注册了要监控文件夹和监控类型。然后,我们进入一个无限循环,在循环中不断获取文件变化事件,并判断事件类型是否为新增文件。如果是新增文件,则输出文件的路径。最后,我们重置监控以便下次继续监控
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值