最近我们组的Mr.S同学到别的项目组里面支援C#去了,
我也借了这个机会多了解了解C#. 这篇blog讨论的文件监视问题也是从这一过程中衍生出来的.
01 C#的文件监视
C#里面有这样一个类:FileSystemWatche. 他可以用来监视文件系统的变化.
他是对mfc的一个封装,C++ native Develop可以直接调用底层的API, 估计Everything就是这么做的.
微软这套东西的好处一定是:
跟操作系统集成得好, 文件有变化的时候系统会通知我们的程序.
我们的程序也不用总是去轮询.
msdn里面的资源还是很丰富,有这样一个例子,很好得展示了这个类的用法:
public class Watcher { public static void Main() { Run(); } [PermissionSet(SecurityAction.Demand, Name="FullTrust")] public static void Run() { string[] args = System.Environment.GetCommandLineArgs(); // If a directory is not specified, exit program. if(args.Length != 2) { // Display the proper way to call the program. Console.WriteLine("Usage: Watcher.exe (directory)"); return; } // Create a new FileSystemWatcher and set its properties. FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = args[1]; /* Watch for changes in LastAccess and LastWrite times, and the renaming of files or directories. */ watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; // Only watch text files. watcher.Filter = "*.txt"; // Add event handlers. watcher.Changed += new FileSystemEventHandler(OnChanged); watcher.Created += new FileSystemEventHandler(OnChanged); watcher.Deleted += new FileSystemEventHandler(OnChanged); watcher.Renamed += new RenamedEventHandler(OnRenamed); // Begin watching. watcher.EnableRaisingEvents = true; // Wait for the user to quit the program. Console.WriteLine("Press \'q\' to quit the sample."); while(Console.Read()!='q'); } // Define the event handlers. private static void OnChanged(object source, FileSystemEventArgs e) { // Specify what is done when a file is changed, created, or deleted. Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); } private static void OnRenamed(object source, RenamedEventArgs e) { // Specify what is done when a file is renamed. Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath); } }
02 Java的文件监视
对"java文件监视"这一功能的需求最初源自于这样一个用例:
一些程序会以ftp的方式向服务器传送一些文件,
如果Client不在每次上传完文件之后,主动调用以通知服务器变更,同时Server端还想即使得知ftp上文件的变化情况.
那么就得在Server端实现ftp文件变化监视这一功能.
而这一功能可以通过Apache Commons Virtual File System 来实现.
虽然vsf的可以实现这一需求, 然而他的功能却不局限于此, 相信看他的名字也能看出来.
他的目的是帮助我们透明的方式操作不同的文件系统(通过它提供的抽象来搬到这一点)
也因此, 监视ftp上文件变化情况的代码, 完全也已用来监视windows上的文件变化情况.
他目前所支持的系统详见这里:Supported File Systems
包括压缩文件,网络文件,CIFS文件,内存文件等等,
我的印象中还支持csv,svn之类....但是刚才看了一下,ms官网上没有记载, 可能是我记错了.
不罗嗦了, vfs监视ftp/windows folder的代码可以像下面这样:
import java.io.File;
import org.apache.commons.vfs.FileChangeEvent;
import org.apache.commons.vfs.FileListener;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.impl.DefaultFileMonitor;
public class TestMonitor {
public static void main(String[] args) throws InterruptedException {
FileSystemManager fsManager = null;
FileObject listendir = null;
try {
fsManager = VFS.getManager();
//monitor path: ftp
listendir = fsManager.resolveFile("ftp://psv:psv@172.17.95.171/incoming/");
//monitor path: windows folder
//listendir = fsManager.resolveFile(new File("C:\\a").getAbsolutePath());
} catch (FileSystemException e) {
System.out.println("Error Occured.");
e.printStackTrace();
}
DefaultFileMonitor fm = new DefaultFileMonitor(new FileListener() {
public void fileCreated(FileChangeEvent event) throws Exception {
monitor(event);
}
public void fileDeleted(FileChangeEvent event) throws Exception {
monitor(event);
}
public void fileChanged(FileChangeEvent event) throws Exception {
monitor(event);
}
private void monitor(FileChangeEvent event) {
FileObject fileObject = event.getFile();
FileName fileName = fileObject.getName();
if (fileName.getBaseName().endsWith(".txt")) {
//reload();
System.out.println("File changed, and the file is: "+fileName);
}else{
System.out.println("A File which is not our interested type(*.txt file) changed.");
}
}
});
fm.setRecursive(true);
fm.addFile(listendir);
fm.start();
Thread.sleep(50000000);
}
}
03 其他
在调查这个问题的过程中L同学告诉我有这样一个类:FileChangeListener
原来他是apache这个包的: apache commons JCI(java compiler interface)