1. 程式人生 > >C#檔案讀寫、操作與監控

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:          }

關於檔案處理的類,還有很多方法和屬性沒辦法講解,都可以參考類的定義來使用。