簡化需求:有一個簡化了的需求是這樣的:有一個拍照程序在運行,一旦抓拍之後則將圖片文件存儲至某目錄,然後圖片要上傳至遠程服務器並update數據庫。
原需求:原先的需求是這樣的:有一台PDA掃碼槍,一個IP照相機放置在下線區傳送帶上方。當PDA掃描箱子上的條碼,觸發相機拍照,將圖片流傳至遠端服務器,找到對應的條碼,將圖片存儲並更新數據庫。
然而我不知道PDA掃描的瞬間如何與IP相機通信(藍牙或WLAN?),其實關鍵是我不知道怎樣使用IP相機的外觸發功能,增加藍牙觸發器?也不知道怎樣hack或ssh到這個相機(應該是linux的吧),所以只能先使用簡化需求的版本。
而簡化需求的版本,關鍵就是監視文件夾內容變化與上傳文件流。
昨天問了下度娘,C#中的監視組件名字叫做FileSystemWatcher。
於是寫了個demo,可以監視所有邏輯盤或者某個文件夾。
使用方法:
1.直接打開是監視所有邏輯磁盤文件變化。

2.或者傳遞參數,監視某一路徑文件變化。如圖,監視e盤

源代碼:
1 namespace FileSystemWatcherDemo
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 //watcher組
8 FileSystemWatcher[] watchers;
9
10 //若未傳遞參數,則監視所有文件系統,包括CD-ROM(不可用),可移動磁盤(不可用)等
11 if (args.Length == 0)
12 {
13 string[] drivers = Directory.GetLogicalDrives();
14 watchers = new FileSystemWatcher[drivers.Length];
15
16 for (int i = 0; i < drivers.Length; i++)
17 {
18 try
19 {
20 watchers[i] = new FileSystemWatcher { Path = drivers[i] };
21 }
22 catch (Exception ex)
23 {
24 Trace.TraceWarning(ex.Message);
25 }
26 }
27 }
28 else
29 {
30 watchers = new FileSystemWatcher[1];
31 watchers[0] = new FileSystemWatcher { Path = args[0] };
32 }
33
34 foreach (FileSystemWatcher w in watchers)
35 {
36 if (w == null) continue;
37
38 w.Filter = "*";
39 w.IncludeSubdirectories = true;
40 w.EnableRaisingEvents = true;
41
42 w.Created += onFileSystem_Changed;
43 w.Deleted += onFileSystem_Changed;
44 w.Changed += onFileSystem_Changed;
45 w.Renamed += watcher_Renamed;
46 }
47
48 Console.ReadLine();
49 }
50
51 #region [ 檢測文件是否占用 ]
52 /// <summary>
53 /// 檢測文件是否占用
54 /// </summary>
55 /// <param name="filename"></param>
56 /// <returns></returns>
57 static bool IsFileReady(string filename)
58 {
59 var fi = new FileInfo(filename);
60 FileStream fs = null;
61 try
62 {
63 fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.None);
64 return true;
65 }
66 catch (IOException)
67 {
68 return false;
69 }
70
71 finally
72 {
73 if (fs != null)
74 fs.Close();
75 }
76 }
77 #endregion
78
79 private static volatile object _lock = true;
80 static void onFileSystem_Changed(object sender, FileSystemEventArgs e)
81 {
82 lock (_lock)
83 {
84 Console.ForegroundColor = ConsoleColor.DarkGray;
85 Console.Write("[");
86 Console.Write(DateTime.Now.ToString("HH:mm:ss"));
87 Console.Write("] ");
88
89 switch (e.ChangeType.ToString().ToLower())
90 {
91 case "created":
92 //while (!IsFileReady(e.FullPath))
93 //{
94 // if (!File.Exists(e.FullPath))
95 // return;
96 // Thread.Sleep(100);
97 //}
98 Console.ForegroundColor = ConsoleColor.Green;
99 Console.Write(e.ChangeType);
100 Console.ForegroundColor = ConsoleColor.White;
101 Console.Write(" ");
102 Console.Write(e.Name);
103 Console.Write(" ");
104 Console.ForegroundColor = ConsoleColor.DarkGray;
105 Console.Write(e.FullPath);
106
107 break;
108 case "deleted":
109 Console.ForegroundColor = ConsoleColor.Red;
110 Console.Write(e.ChangeType);
111 Console.ForegroundColor = ConsoleColor.White;
112 Console.Write(" ");
113 Console.Write(e.Name);
114 Console.Write(" ");
115 Console.ForegroundColor = ConsoleColor.DarkGray;
116 Console.Write(e.FullPath);
117 break;
118 case "changed":
119 Console.ForegroundColor = ConsoleColor.Cyan;
120 Console.Write(e.ChangeType);
121 Console.ForegroundColor = ConsoleColor.White;
122 Console.Write(" ");
123 Console.Write(e.Name);
124 Console.Write(" ");
125 Console.ForegroundColor = ConsoleColor.DarkGray;
126 Console.Write(e.FullPath);
127 break;
128 }
129
130 Console.Write("\r\n");
131 }
132 }
133 static void watcher_Renamed(object sender, RenamedEventArgs e)
134 {
135 Console.ForegroundColor = ConsoleColor.Magenta;
136 Console.Write(e.ChangeType);
137 Console.ForegroundColor = ConsoleColor.White;
138 Console.Write(" ");
139 Console.Write(e.OldName);
140 Console.Write(e.OldFullPath);
141 Console.ForegroundColor = ConsoleColor.Yellow;
142 Console.Write(" ");
143 Console.Write(e.Name);
144 Console.Write(e.FullPath);
145 Console.Write(Thread.CurrentThread.Name);
146 Console.Write("\r\n");
147 }
148 }
149 }
仍有bug,望高手指正。
附上編譯好的exe,可以直接運行。