简化需求
有一个简化了的需求是这样的:有一个拍照程序在运行,一旦抓拍之后则将图片文件存储至某目录,然后图片要上传至远程服务器并update数据库。
原需求
原先的需求是这样的:有一台PDA扫码枪,一个IP照相机放置在下线区传送带上方。当PDA扫描箱子上的条码,触发相机拍照,将图片流传至远端服务器,找到对应的条码,将图片存储并更新数据库。
然而我不知道PDA扫描的瞬间如何与IP相机通信(蓝牙或WLAN?),其实关键是我不知道怎样使用IP相机的外触发功能,增加蓝牙触发器?也不知道怎样hack或ssh到这个相机(应该是linux的吧),所以只能先使用简化需求的版本。
而简化需求的版本,关键就是监视文件夹内容变化与上传文件流。
昨天问了下度娘,C#中的监视组件名字叫做FileSystemWatcher。
于是写了个demo,可以监视所有逻辑盘或者某个文件夹。
使用方法:
直接打开是监视所有逻辑磁盘文件变化。
或者传递参数,监视某一路径文件变化。如图,监视e盘
源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| namespace FileSystemWatcherDemo { class Program { static void Main(string[] args) { //watcher组 FileSystemWatcher[] watchers;
//若未传递参数,则监视所有文件系统,包括CD-ROM(不可用),可移动磁盘(不可用)等 if (args.Length == 0) { string[] drivers = Directory.GetLogicalDrives(); watchers = new FileSystemWatcher[drivers.Length];
for (int i = 0; i < drivers.Length; i++) { try { watchers[i] = new FileSystemWatcher { Path = drivers[i] }; } catch (Exception ex) { Trace.TraceWarning(ex.Message); } } } else { watchers = new FileSystemWatcher[1]; watchers[0] = new FileSystemWatcher { Path = args[0] }; }
foreach (FileSystemWatcher w in watchers) { if (w == null) continue;
w.Filter = "*"; w.IncludeSubdirectories = true; w.EnableRaisingEvents = true;
w.Created += onFileSystem_Changed; w.Deleted += onFileSystem_Changed; w.Changed += onFileSystem_Changed; w.Renamed += watcher_Renamed; }
Console.ReadLine(); }
#region [ 检测文件是否占用 ] /// <summary> /// 检测文件是否占用 /// </summary> /// <param name="filename"></param> /// <returns></returns> static bool IsFileReady(string filename) { var fi = new FileInfo(filename); FileStream fs = null; try { fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.None); return true; } catch (IOException) { return false; }
finally { if (fs != null) fs.Close(); } } #endregion
private static volatile object _lock = true; static void onFileSystem_Changed(object sender, FileSystemEventArgs e) { lock (_lock) { Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write("["); Console.Write(DateTime.Now.ToString("HH:mm:ss")); Console.Write("] ");
switch (e.ChangeType.ToString().ToLower()) { case "created": //while (!IsFileReady(e.FullPath)) //{ // if (!File.Exists(e.FullPath)) // return; // Thread.Sleep(100); //} Console.ForegroundColor = ConsoleColor.Green; Console.Write(e.ChangeType); Console.ForegroundColor = ConsoleColor.White; Console.Write(" "); Console.Write(e.Name); Console.Write(" "); Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write(e.FullPath);
break; case "deleted": Console.ForegroundColor = ConsoleColor.Red; Console.Write(e.ChangeType); Console.ForegroundColor = ConsoleColor.White; Console.Write(" "); Console.Write(e.Name); Console.Write(" "); Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write(e.FullPath); break; case "changed": Console.ForegroundColor = ConsoleColor.Cyan; Console.Write(e.ChangeType); Console.ForegroundColor = ConsoleColor.White; Console.Write(" "); Console.Write(e.Name); Console.Write(" "); Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write(e.FullPath); break; }
Console.Write("\r\n"); } } static void watcher_Renamed(object sender, RenamedEventArgs e) { Console.ForegroundColor = ConsoleColor.Magenta; Console.Write(e.ChangeType); Console.ForegroundColor = ConsoleColor.White; Console.Write(" "); Console.Write(e.OldName); Console.Write(e.OldFullPath); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write(" "); Console.Write(e.Name); Console.Write(e.FullPath); Console.Write(Thread.CurrentThread.Name); Console.Write("\r\n"); } } }
|
仍有bug,望高手指正。
附上编译好的exe,可以直接运行。
文章最初发表于博客园:http://www.cnblogs.com/LisonLiou/p/filesystemwatcher.html