程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# FileStream文件讀寫詳解

C# FileStream文件讀寫詳解

編輯:C#入門知識

C# FileStream文件讀寫詳解。本站提示廣大學習愛好者:(C# FileStream文件讀寫詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C# FileStream文件讀寫詳解正文


FileStream對象表現在磁盤或收集途徑上指向文件的流。這個類供給了在文件中讀寫字節的辦法,但常常應用StreamReader或StreamWriter履行這些功效。這是由於FileStream類操作的是字節和字節數組,而Stream類操作的是字符數據。字符數據易於應用,然則有些操作,好比隨機文件拜訪(拜訪文件中央某點的數據),就必需由FileStream對象履行,稍後對此停止引見。

還有幾種辦法可以創立FileStream對象。結構函數具有很多分歧的重載版本,最簡略的結構函數僅僅帶有兩個參數,即文件名和FileMode列舉值。


FileStream aFile = new FileStream(filename, FileMode.Member);

FileMode列舉有幾個成員,劃定了若何翻開或創立文件。稍後引見這些列舉成員。另外一個經常使用的結構函數以下:


FileStream aFile = new FileStream(filename, FileMode.Member, FileAccess. Member);

第三個參數是FileAccess列舉的一個成員,它指定了流的感化。FileAccess列舉的成員如表22-6所示。

表  22-6

成員 解釋 Read 翻開文件,用於只讀 Write 翻開文件,用於只寫 ReadWrite 翻開文件,用於讀寫

對文件停止不是FileAccess列舉成員指定的操作會招致拋出異常。此屬性的感化是,基於用戶的身份驗證級別轉變用戶對文件的拜訪權限。

在FileStream結構函數不應用FileAccess列舉參數的版本中,應用默許值FileAccess. ReadWrite。

FileMode列舉成員如表22-7所示。應用每一個值會產生甚麼,取決於指定的文件名能否表現已有的文件。留意這個表中的項表現創立流時該流指向文件中的地位,下一節將具體評論辯論這個主題。除非特殊解釋,不然流就指向文件的開首。

表  22-7

成員 文件存在 文件不存在 Append 翻開文件,流指向文件的末尾,只能與列舉FileAccess.Write結合應用 創立一個新文件。只能與列舉FileAccess.Write結合應用 Create 刪除該文件,然後創立新文件 創立新文件 CreateNew 拋出異常 創立新文件 Open 翻開現有的文件,流指向文件的開首 拋出異常 OpenOrCreate 翻開文件,流指向文件的開首 創立新文件 Truncate 翻開現有文件,消除其內容。流指向文件的開首,保存文件的初始創立日期 拋出異常

File和FileInfo類都供給了OpenRead()和OpenWrite()辦法,更容易於創立FileStream對象。前者翻開了只讀拜訪的文件,後者只許可寫入文件。這些都供給了快捷方法,是以不用以FileStream結構函數的參數情勢供給後面一切的信息。例如,上面的代碼行翻開了用於只讀拜訪的Data.txt文件:


FileStream aFile = File.OpenRead("Data.txt");

留意上面的代碼履行異樣的功效:


FileInfo aFileInfo = new FileInfo("Data.txt");
FileStream aFile = aFile.OpenRead();

1. 文件地位

FileStream類保護外部文件指針,該指針指向文件中停止下一次讀寫操作的地位。在年夜多半情形下,當翻開文件時,它就指向文件的開端地位,然則此指針可以修正。這許可運用法式在文件的任何地位讀寫,隨機拜訪文件,或直接跳到文件的特定地位上。當處置年夜型文件時,這異常省時,由於立時可以定位到准確的地位。

完成此功效的辦法是Seek()辦法,它有兩個參數:第一個參數劃定文件指針以字節為單元的挪動間隔。第二個參數劃定開端盤算的肇端地位,用SeekOrigin列舉的一個值表現。Seek Origin列舉包括3個值:Begin、Current和End。

例如,上面的代碼即將文件指針挪動到文件的第8個字節,其肇端地位就是文件的第1個字節:


aFile.Seek(8,SeekOrigin.Begin);

上面的代碼即將指針從以後地位開端向前挪動2個字節。假如在下面的代碼行以後履行上面的代碼,文件指針就指向文件的第10個字節:


aFile.Seek(2,SeekOrigin.Current);

留意讀寫文件時,文件指針也會轉變。在讀取了10個字節以後,文件指針就指向被讀取的第10個字節以後的字節。

也能夠劃定負查找地位,這可以與SeekOrigin.End列舉值一路應用,查找接近文件末尾的地位。上面的代碼會查找文件中倒數第5個字節:


aFile.Seek(–5, SeekOrigin.End);

以這類方法拜訪的文件有時稱為隨機拜訪文件,由於運用法式可以拜訪文件中的任何地位。稍後引見的Stream類可以持續地拜訪文件,不許可以這類方法操作文件指針。

2. 讀取數據

應用FileStream類讀取數據不像應用本章前面引見的StreamReader類讀取數據那樣輕易。這是由於FileStream類只能處置原始字節(raw byte)。處置原始字節的功效使FileStream類可以用於任何數據文件,而不只僅是文本文件。經由過程讀取字節數據,FileStream對象可以用於讀取圖象和聲響的文件。這類靈巧性的價值是,不克不及應用FileStream類將數據直接讀入字符串,而應用StreamReader類卻可以如許處置。然則有幾種轉換類可以很輕易地將字節數組轉換為字符數組,或許停止相反的操作。

FileStream.Read()辦法是從FileStream對象所指向的文件中拜訪數據的重要手腕。這個辦法從文件中讀取數據,再把數據寫入一個字節數組。它有三個參數:第一個參數是傳輸出去的字節數組,用以接收FileStream對象中的數據。第二個參數是字節數組中開端寫入數據的地位。它平日是0,表現從數組開始向文件中寫入數據。最初一個參數指定從文件中讀出若干字節。

上面的示例演示了從隨機拜訪文件中讀取數據。要讀取的文件現實是為此示例創立的類文件。

嘗嘗看:從隨機拜訪文件中讀取數據

(1) 在目次C:\BegVCSharp\Chapter22下創立一個新的掌握台運用法式ReadFile。

(2) 在Program.cs文件的頂部添加上面的using指令:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

(3) 在Main()辦法中添加上面的代碼:


static void Main(string[] args)
{
   byte[] byData = new byte[200];
   char[] charData = new Char[200];
 
   try
   {
      FileStream aFile = new FileStream("E:\\Workplace\\TestSolution\\Test.ConsoleApplication\\Program.cs",FileMode.Open);
      aFile.Seek(135,SeekOrigin.Begin);
      aFile.Read(byData,0,200);
   }
   catch(IOException e)
   {
      Console.WriteLine("An IO exception has been thrown!");
      Console.WriteLine(e.ToString());
      Console.ReadKey();
      return;
  }
 
   Decoder d = Encoding.UTF8.GetDecoder();
   d.GetChars(byData, 0, byData.Length, charData, 0);
 
   Console.WriteLine(charData);
   Console.ReadKey();
}

(4) 運轉運用法式。成果如圖22-2所示。

FileStream讀取數據

圖 22-2

示例的解釋
此運用法式翻開本身的.cs文件,用於讀取。它鄙人面的代碼行中應用..字符串向上逐級導航兩個目次,找到該文件:


FileStream aFile = new FileStream("E:\\Workplace\\TestSolution\\Test.ConsoleApplication\\Program.cs",FileMode.Open);

上面兩行代碼完成查找任務,並從文件的詳細地位讀取字節:


aFile.Seek(135,SeekOrigin.Begin);
aFile.Read(byData,0,200);

第一行代碼將文件指針挪動到文件的第135個字節。在Program.cs中,這是namespace的 “n”;其後面的135個字符是using指令和相干的#region。第二即將接上去的200個字節讀入到byData字節數組中。

留意這兩行代碼封裝在try…catch塊中,以處置能夠拋出的異常。


try
{
    aFile.Seek(135,SeekOrigin.Begin);
    aFile.Read(byData,0,100);
}
catch(IOException e)
{
    Console.WriteLine("An IO exception has been thrown!");
    Console.WriteLine(e.ToString());
    Console.ReadKey();
    return;
}

文件IO觸及到的一切操作都可以拋出類型為IOException的異常。一切產物代碼都必需包括毛病處置,特別是處置文件體系時更是如斯。本章的一切示例都具有毛病處置的根本情勢。

從文件中獲得了字節數組後,就須要將其轉換為字符數組,以便在掌握台顯示它。為此,應用System.Text定名空間的Decoder類。此類用於將原始字節轉換為更有效的項,好比字符:


Decoder d = Encoding.UTF8.GetDecoder();
d.GetChars(byData, 0, byData.Length, charData, 0);

這些代碼基於UTF8編碼形式創立了Decoder對象。這就是Unicode編碼形式。然後挪用GetChars()辦法,此辦法提取字節數組,將它轉換為字符數組。完成以後,便可以將字符數組輸入到掌握台。

3. 寫入數據

向隨機拜訪文件中寫入數據的進程與從中讀取數據異常相似。起首須要創立一個字節數組;最簡略的方法是起首構建要寫入文件的字符數組。然後應用Encoder對象將其轉換為字節數組,其用法異常相似於Decoder。最初挪用Write()辦法,將字節數組傳送到文件中。

上面構建一個簡略的示例演示其進程。

嘗嘗看:將數據寫入隨機拜訪文件

(1) 在C:\BegVCSharp\Chapter22目次下創立一個新的掌握台運用法式WriteFile。

(2) 如上所示,在Program.cs文件頂部添加上面的using指令:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

(3) 在Main()辦法中添加上面的代碼:


static void Main(string[] args)
{
   byte[] byData;
   char[] charData;
 
   try
   {
      FileStream aFile = new FileStream("Temp.txt", FileMode.Create);
      charData = "My pink half of the drainpipe.".ToCharArray();
      byData = new byte[charData.Length];
      Encoder e = Encoding.UTF8.GetEncoder();
      e.GetBytes(charData, 0, charData.Length, byData, 0, true);
 
      // Move file pointer to beginning of file.
      aFile.Seek(0, SeekOrigin.Begin);
      aFile.Write(byData, 0, byData.Length);
   }
   catch (IOException ex)
   {
      Console.WriteLine("An IO exception has been thrown!");
      Console.WriteLine(ex.ToString());
      Console.ReadKey();
      return;
   }
}

(4) 運轉該運用法式。稍後就將其封閉。

(5) 導航到運用法式目次 —— 在目次中曾經保留了文件,由於我們應用了絕對途徑。目次位於WriteFile\bin\Debug文件夾。翻開Temp.txt文件。可以在文件中看到如圖22-3所示的文本。

FileStream寫入數據

圖 22-3

示例的解釋
此運用法式在本身的目次中翻開文件,並在文件中寫入了一個簡略的字符串。在構造上這個示例異常相似於後面的示例,只是用Write()取代了Read(),用Encoder取代了Decoder。

上面的代碼行應用String類的ToCharArray()靜態辦法,創立了字符數組。由於C#中的一切事物都是對象,文本“My pink half of the drainpipe.”現實上是一個String對象,所以乃至可以在字符串上挪用這些靜態辦法。


CharData = " My pink half of the drainpipe. ".ToCharArray();

上面的代碼行顯示了若何將字符數組轉換為FileStream對象須要的准確字節數組。


Encoder e = Endoding.UTF8.GetEncoder();
e.GetBytes(charData,0,charData.Length, byData,0,true);

此次,要基於UTF8編碼辦法來創立Encoder對象。也能夠將Unicode用於解碼。這裡在寫入流之前,須要將字符數據編碼為准確的字節格局。在GetBytes()辦法中可以完成這些任務,它可以將字符數組轉換為字節數組,並將字符數組作為第一個參數(本例中的charData),將該數組中肇端地位的下標作為第二個參數(0表現數組的開首)。第三個參數是要轉換的字符數目(charData.Length,charData數組中的元素個數)。第四個參數是在個中置入數據的字節數組(byData),第五個參數是在字節數組中開端寫入地位的下標(0表現byData數組的開首)。

最初一個參數決議在停止後Encoder對象能否應當更新其狀況,即Encoder對象能否依然保存它本來在字節數組中的內存地位。這有助於今後挪用Encoder對象,然則當只停止單一挪用時,這就沒有甚麼意義。最初對Encoder的挪用必需將此參數設置為true,以清空其內存,釋放對象,用於渣滓收受接管。

以後,應用Write()辦法向FileStream寫入字節數組就異常簡略:


aFile.Seek(0,SeekOrigin.Begin);
aFile.Write(byData,0,byData.Length);

與Read()辦法一樣,Write()辦法也有三個參數:要寫入的數組,開端寫入的數組下標和要寫入的字節數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved