C#檔案讀寫、操作與監控
關於檔案系統操作的幾個常用類和使用
流結構和檔案的二進位制和字元讀寫
檔案監控類FileSystemWatcher的使用
首先先看一張C#常用與檔案操作有關的類圖
所有的這些類都在System.IO的名稱空間中,所以一下的所有程式碼,使用時都要先新增
using System.IO;
另外在這部分程式中出現異常均為IOException
開始介紹一下檔案和目錄的操作。
檔案使用FileInfo類或File類。區別是FileInfo有生成一個例項,而File類只是一個靜態類。如果對檔案只需要進行一次性操作,使用File類會更好。下面程式碼展示FileInfo類的使用,File類使用類似。更多的方法可以直接轉到FileInfo的類定義中檢視。
1: static void Main(string[] args)
2: {
3: FileInfo test;
4: try
5: {
6: test = new FileInfo(@"D:/test.txt");
7: if (!test.Exists)//檔案是否存在
8: {
9:test.Create();//建立檔案
10: }
11: //第二個引數表示是否允許覆蓋現有檔案。
12: //test.CopyTo(@"E:/test.txt",false);
13: Console.WriteLine("目錄名: {0}", test.DirectoryName);
14: Console.WriteLine("檔名: {0}", test.Name);
15: Console.WriteLine("檔案大小為{0}位元組", test.Length);
16: //test.Delete();刪除檔案
17: //test.MoveTo(@"D:/1.txt");移動/重新命名
18: }
19: catch (IOException e)
20: {
21: Console.WriteLine(e.Message);
22: }
23: Console.ReadKey();
24: }
對於目錄的操作也是類似的分為了DirectoryInfo和Directory兩個類。
所能實現的方法可以直接參考定義,都不難理解。但是定義中沒有提供整個目錄的複製功能。需要自己遞迴實現,具體看以下程式碼
1: static void CopyDirectory(DirectoryInfo source, DirectoryInfo destination)
2: {
3: try
4: {
5: if (!destination.Exists)
6: {
7: destination.Create();
8: }
9:
10: FileInfo[] files = source.GetFiles();
11: foreach (FileInfo file in files)
12: {
13: file.CopyTo(destination.FullName + file.Name);
14: }
15:
16: DirectoryInfo[] directorys = source.GetDirectories();
17: foreach (DirectoryInfo directory in directorys)
18: {
19: //構建目標子目錄的絕對地址,目標目錄地址+資料夾名
20: string newDirName = Path.Combine(destination.FullName,directory.Name);
21: //複製子目錄
22: CopyDirectory(directory, new DirectoryInfo(newDirName));
23: }
24: }
25: catch (IOException e)
26: {
27: Console.WriteLine(e.Message);
28: }
29:
30: }
31: static void Main(string[] args)
32: {
33: try
34: {
35: DirectoryInfo test = new DirectoryInfo(@"D:/test");
36: if (!test.Exists)
37: {
38: test.Create();
39: }
40: CopyDirectory(test, new DirectoryInfo(@"E:/test"));
41:
42: }
43: catch (IOException e)
44: {
45: Console.WriteLine(e.Message);
46: }
47: Console.ReadKey();
48: }
49:
以上介紹的都是檔案和目錄級別的操作下面介紹檔案的讀寫。
檔案的讀寫分為兩種模式,一種是按二進位制方式讀寫,另一種按文字方式讀寫。分別用於一般二進位制檔案和文字檔案。
在給程式碼前有兩個知識點需要提一下。
一個是我們的硬碟磁碟都是以線性方式儲存資料,所以我們就可以構建一個流結構來對檔案進行讀寫。通過流結構,讓資料流向檔案,或者是讓檔案內容流向變數。
另一個是檔案指標。就是一個指向我們將要操作的位置。比如我們檔案指標位於檔案的第10個位元組,我們的讀寫操作都是從檔案指標的位置即第10個位元組開始。相當於我們編輯檔案時能看到的游標。可以用Seek()方法進行操作。
首先我們先看如何讀寫二進位制檔案,使用FileStream類。下面程式碼實現向image.ima寫入boot.bin。注意這裡是寫入,不是插入,假設我們boot.bin的檔案大小為N個位元組,那麼讀寫完後image.imz原來開頭的N個位元組的內容就被修改掉了,而第N+1及之後的內容不變。
1: static void Main(string[] args)
2: {
3: FileStream source = null;
4: FileStream destination = null;
5: try
6: {
7: source = new FileStream(@"D:/boot.bin", FileMode.Open, FileAccess.Read);
8: destination = new FileStream(@"D:/image.imz", FileMode.Open, FileAccess.Write);
9: byte[] buffer = new byte[215];
10: int count = 0;
11: count = source.Read(buffer, 0, 215);
12: while (count != 0)
13: {
14: destination.Write(buffer, 0, count);
15: count = source.Read(buffer, 0, 215);
16: }
17: Console.WriteLine("OK");
18: }
19: catch (IOException e)
20: {
21: Console.WriteLine(e.Message);
22: }
23: finally
24: {
25: if (source != null)
26: {
27: source.Close();
28: }
29: if (destination != null)
30: {
31: destination.Close();
32: }
33: }
34: Console.ReadKey();
35: }
建立FileSream的時候後面兩個引數是列舉型別,設定了檔案的模式和許可權。
如果要對文字檔案進行讀寫需要用到StreamWriter和StreamReader類。初始化他們的時候最好使用FileStream作為引數,不然那兩個類無法設定檔案的訪問許可權,預設都是可以讀寫的。
具體的使用方法參考下面程式碼
1: static void Main(string[] args)
2: {
3: FileStream file = null;
4: StreamWriter sw = null;
5: StreamReader sr = null;
6: string[][] table = new string[3][];
7: table[0] = new string[3] { "11", "22", "33" };
8: table[1] = new string[3] { "44", "55", "66" };
9: table[2] = new string[3] { "77", "88", "99" };
10: try
11: {
12: file = new FileStream(@"D:/test.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
13:
14: sw = new StreamWriter(file);
15: foreach (string[] i in table)
16: {
17: foreach (string str in i)
18: {
19: Console.Write("{0} ",str);
20: sw.Write("{0} ",str);
21: }
22: Console.WriteLine();
23: sw.WriteLine();
24: }
25: sw.Flush();//把快取區內容輸出
26: Console.WriteLine("write");
27:
28: file.Seek(0, SeekOrigin.Begin);//把檔案指標移到檔案頭
29: sr = new StreamReader(file);
30: string strline = sr.ReadLine();
31: while (strline != null)
32: {
33: string[] strElement = strline.Split(' ');
34: foreach (string element in strElement)
35: {
36: Console.Write("{0} ", element);
37: }
38: Console.WriteLine();
39:
40: strline = sr.ReadLine();
41: }
42: Console.WriteLine("read");
43: }
44: catch (IOException e)
45: {
46: Console.WriteLine(e.Message);
47: }
48: finally
49: {
50: if (sw != null)
51: {
52: sw.Close();
53: }
54: if (sr != null)
55: {
56: sr.Close();
57: }
58: if (file != null)
59: {
60: file.Close();
61: }
62: }
63: Console.ReadKey();
64: }
最後介紹一個檔案監控例項,利用FileSystemWatcher可以監控檔案的修改,刪除,建立,重新命名等事件。只要新增相應的事件處理函式,就可以在方式相應事件時執行函式。
下面的程式碼監控了檔案的刪除事件,其他的事件可以仿照刪除時間處理函式進行處理
1: static void Main(string[] args)
2: {
3: FileSystemWatcher watcher = new FileSystemWatcher(@"D:/","1.txt");
4: watcher.Deleted += OnDelete;
5: watcher.EnableRaisingEvents = true;
6:
7: Console.ReadKey();
8:
9: }
10: static void OnDelete(object sender, FileSystemEventArgs e)
11: {
12: Console.WriteLine("{0} had been deleted!", e.FullPath);
13: }
關於檔案處理的類,還有很多方法和屬性沒辦法講解,都可以參考類的定義來使用。