最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# FileStream文件讀寫(xiě)詳解

 更新時(shí)間:2016年04月26日 14:50:13   作者:Fskjb  
本文主要介紹C#使用 FileStream 讀取數(shù)據(jù),寫(xiě)入數(shù)據(jù)等操作,希望能幫到大家。

FileStream對(duì)象表示在磁盤(pán)或網(wǎng)絡(luò)路徑上指向文件的流。這個(gè)類(lèi)提供了在文件中讀寫(xiě)字節(jié)的方法,但經(jīng)常使用StreamReader或StreamWriter執(zhí)行這些功能。這是因?yàn)镕ileStream類(lèi)操作的是字節(jié)和字節(jié)數(shù)組,而Stream類(lèi)操作的是字符數(shù)據(jù)。字符數(shù)據(jù)易于使用,但是有些操作,比如隨機(jī)文件訪問(wèn)(訪問(wèn)文件中間某點(diǎn)的數(shù)據(jù)),就必須由FileStream對(duì)象執(zhí)行,稍后對(duì)此進(jìn)行介紹。

還有幾種方法可以創(chuàng)建FileStream對(duì)象。構(gòu)造函數(shù)具有許多不同的重載版本,最簡(jiǎn)單的構(gòu)造函數(shù)僅僅帶有兩個(gè)參數(shù),即文件名和FileMode枚舉值。

復(fù)制代碼 代碼如下:

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

FileMode枚舉有幾個(gè)成員,規(guī)定了如何打開(kāi)或創(chuàng)建文件。稍后介紹這些枚舉成員。另一個(gè)常用的構(gòu)造函數(shù)如下:

復(fù)制代碼 代碼如下:

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

第三個(gè)參數(shù)是FileAccess枚舉的一個(gè)成員,它指定了流的作用。FileAccess枚舉的成員如表22-6所示。

表  22-6

成員 說(shuō)明
Read 打開(kāi)文件,用于只讀
Write 打開(kāi)文件,用于只寫(xiě)
ReadWrite 打開(kāi)文件,用于讀寫(xiě)

對(duì)文件進(jìn)行不是FileAccess枚舉成員指定的操作會(huì)導(dǎo)致拋出異常。此屬性的作用是,基于用戶(hù)的身份驗(yàn)證級(jí)別改變用戶(hù)對(duì)文件的訪問(wèn)權(quán)限。

在FileStream構(gòu)造函數(shù)不使用FileAccess枚舉參數(shù)的版本中,使用默認(rèn)值FileAccess. ReadWrite。

FileMode枚舉成員如表22-7所示。使用每個(gè)值會(huì)發(fā)生什么,取決于指定的文件名是否表示已有的文件。注意這個(gè)表中的項(xiàng)表示創(chuàng)建流時(shí)該流指向文件中的位置,下一節(jié)將詳細(xì)討論這個(gè)主題。除非特別說(shuō)明,否則流就指向文件的開(kāi)頭。

表  22-7

成員 文件存在 文件不存在
Append 打開(kāi)文件,流指向文件的末尾,只能與枚舉FileAccess.Write聯(lián)合使用 創(chuàng)建一個(gè)新文件。只能與枚舉FileAccess.Write聯(lián)合使用
Create 刪除該文件,然后創(chuàng)建新文件 創(chuàng)建新文件
CreateNew 拋出異常 創(chuàng)建新文件
Open 打開(kāi)現(xiàn)有的文件,流指向文件的開(kāi)頭 拋出異常
OpenOrCreate 打開(kāi)文件,流指向文件的開(kāi)頭 創(chuàng)建新文件
Truncate 打開(kāi)現(xiàn)有文件,清除其內(nèi)容。流指向文件的開(kāi)頭,保留文件的初始創(chuàng)建日期 拋出異常

File和FileInfo類(lèi)都提供了OpenRead()和OpenWrite()方法,更易于創(chuàng)建FileStream對(duì)象。前者打開(kāi)了只讀訪問(wèn)的文件,后者只允許寫(xiě)入文件。這些都提供了快捷方式,因此不必以FileStream構(gòu)造函數(shù)的參數(shù)形式提供前面所有的信息。例如,下面的代碼行打開(kāi)了用于只讀訪問(wèn)的Data.txt文件:

復(fù)制代碼 代碼如下:

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

注意下面的代碼執(zhí)行同樣的功能:

復(fù)制代碼 代碼如下:

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

1. 文件位置

FileStream類(lèi)維護(hù)內(nèi)部文件指針,該指針指向文件中進(jìn)行下一次讀寫(xiě)操作的位置。在大多數(shù)情況下,當(dāng)打開(kāi)文件時(shí),它就指向文件的開(kāi)始位置,但是此指針可以修改。這允許應(yīng)用程序在文件的任何位置讀寫(xiě),隨機(jī)訪問(wèn)文件,或直接跳到文件的特定位置上。當(dāng)處理大型文件時(shí),這非常省時(shí),因?yàn)轳R上可以定位到正確的位置。

實(shí)現(xiàn)此功能的方法是Seek()方法,它有兩個(gè)參數(shù):第一個(gè)參數(shù)規(guī)定文件指針以字節(jié)為單位的移動(dòng)距離。第二個(gè)參數(shù)規(guī)定開(kāi)始計(jì)算的起始位置,用SeekOrigin枚舉的一個(gè)值表示。Seek Origin枚舉包含3個(gè)值:Begin、Current和End。

例如,下面的代碼行將文件指針移動(dòng)到文件的第8個(gè)字節(jié),其起始位置就是文件的第1個(gè)字節(jié):

復(fù)制代碼 代碼如下:

aFile.Seek(8,SeekOrigin.Begin);

下面的代碼行將指針從當(dāng)前位置開(kāi)始向前移動(dòng)2個(gè)字節(jié)。如果在上面的代碼行之后執(zhí)行下面的代碼,文件指針就指向文件的第10個(gè)字節(jié):

復(fù)制代碼 代碼如下:

aFile.Seek(2,SeekOrigin.Current);

注意讀寫(xiě)文件時(shí),文件指針也會(huì)改變。在讀取了10個(gè)字節(jié)之后,文件指針就指向被讀取的第10個(gè)字節(jié)之后的字節(jié)。

也可以規(guī)定負(fù)查找位置,這可以與SeekOrigin.End枚舉值一起使用,查找靠近文件末端的位置。下面的代碼會(huì)查找文件中倒數(shù)第5個(gè)字節(jié):

復(fù)制代碼 代碼如下:

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

以這種方式訪問(wèn)的文件有時(shí)稱(chēng)為隨機(jī)訪問(wèn)文件,因?yàn)閼?yīng)用程序可以訪問(wèn)文件中的任何位置。稍后介紹的Stream類(lèi)可以連續(xù)地訪問(wèn)文件,不允許以這種方式操作文件指針。

2. 讀取數(shù)據(jù)

使用FileStream類(lèi)讀取數(shù)據(jù)不像使用本章后面介紹的StreamReader類(lèi)讀取數(shù)據(jù)那樣容易。這是因?yàn)镕ileStream類(lèi)只能處理原始字節(jié)(raw byte)。處理原始字節(jié)的功能使FileStream類(lèi)可以用于任何數(shù)據(jù)文件,而不僅僅是文本文件。通過(guò)讀取字節(jié)數(shù)據(jù),F(xiàn)ileStream對(duì)象可以用于讀取圖像和聲音的文件。這種靈活性的代價(jià)是,不能使用FileStream類(lèi)將數(shù)據(jù)直接讀入字符串,而使用StreamReader類(lèi)卻可以這樣處理。但是有幾種轉(zhuǎn)換類(lèi)可以很容易地將字節(jié)數(shù)組轉(zhuǎn)換為字符數(shù)組,或者進(jìn)行相反的操作。

FileStream.Read()方法是從FileStream對(duì)象所指向的文件中訪問(wèn)數(shù)據(jù)的主要手段。這個(gè)方法從文件中讀取數(shù)據(jù),再把數(shù)據(jù)寫(xiě)入一個(gè)字節(jié)數(shù)組。它有三個(gè)參數(shù):第一個(gè)參數(shù)是傳輸進(jìn)來(lái)的字節(jié)數(shù)組,用以接受FileStream對(duì)象中的數(shù)據(jù)。第二個(gè)參數(shù)是字節(jié)數(shù)組中開(kāi)始寫(xiě)入數(shù)據(jù)的位置。它通常是0,表示從數(shù)組開(kāi)端向文件中寫(xiě)入數(shù)據(jù)。最后一個(gè)參數(shù)指定從文件中讀出多少字節(jié)。

下面的示例演示了從隨機(jī)訪問(wèn)文件中讀取數(shù)據(jù)。要讀取的文件實(shí)際是為此示例創(chuàng)建的類(lèi)文件。

試試看:從隨機(jī)訪問(wèn)文件中讀取數(shù)據(jù)

(1) 在目錄C:\BegVCSharp\Chapter22下創(chuàng)建一個(gè)新的控制臺(tái)應(yīng)用程序ReadFile。

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

復(fù)制代碼 代碼如下:

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

(3) 在Main()方法中添加下面的代碼:

復(fù)制代碼 代碼如下:

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) 運(yùn)行應(yīng)用程序。結(jié)果如圖22-2所示。

FileStream讀取數(shù)據(jù)

圖 22-2

示例的說(shuō)明
此應(yīng)用程序打開(kāi)自己的.cs文件,用于讀取。它在下面的代碼行中使用..字符串向上逐級(jí)導(dǎo)航兩個(gè)目錄,找到該文件:

復(fù)制代碼 代碼如下:

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

下面兩行代碼實(shí)現(xiàn)查找工作,并從文件的具體位置讀取字節(jié):

復(fù)制代碼 代碼如下:

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

第一行代碼將文件指針移動(dòng)到文件的第135個(gè)字節(jié)。在Program.cs中,這是namespace的 “n”;其前面的135個(gè)字符是using指令和相關(guān)的#region。第二行將接下來(lái)的200個(gè)字節(jié)讀入到byData字節(jié)數(shù)組中。

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

復(fù)制代碼 代碼如下:

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涉及到的所有操作都可以拋出類(lèi)型為IOException的異常。所有產(chǎn)品代碼都必須包含錯(cuò)誤處理,尤其是處理文件系統(tǒng)時(shí)更是如此。本章的所有示例都具有錯(cuò)誤處理的基本形式。

從文件中獲取了字節(jié)數(shù)組后,就需要將其轉(zhuǎn)換為字符數(shù)組,以便在控制臺(tái)顯示它。為此,使用System.Text命名空間的Decoder類(lèi)。此類(lèi)用于將原始字節(jié)轉(zhuǎn)換為更有用的項(xiàng),比如字符:

復(fù)制代碼 代碼如下:

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

這些代碼基于UTF8編碼模式創(chuàng)建了Decoder對(duì)象。這就是Unicode編碼模式。然后調(diào)用GetChars()方法,此方法提取字節(jié)數(shù)組,將它轉(zhuǎn)換為字符數(shù)組。完成之后,就可以將字符數(shù)組輸出到控制臺(tái)。

3. 寫(xiě)入數(shù)據(jù)

向隨機(jī)訪問(wèn)文件中寫(xiě)入數(shù)據(jù)的過(guò)程與從中讀取數(shù)據(jù)非常類(lèi)似。首先需要?jiǎng)?chuàng)建一個(gè)字節(jié)數(shù)組;最簡(jiǎn)單的辦法是首先構(gòu)建要寫(xiě)入文件的字符數(shù)組。然后使用Encoder對(duì)象將其轉(zhuǎn)換為字節(jié)數(shù)組,其用法非常類(lèi)似于Decoder。最后調(diào)用Write()方法,將字節(jié)數(shù)組傳送到文件中。

下面構(gòu)建一個(gè)簡(jiǎn)單的示例演示其過(guò)程。

試試看:將數(shù)據(jù)寫(xiě)入隨機(jī)訪問(wèn)文件

(1) 在C:\BegVCSharp\Chapter22目錄下創(chuàng)建一個(gè)新的控制臺(tái)應(yīng)用程序WriteFile。

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

復(fù)制代碼 代碼如下:

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

(3) 在Main()方法中添加下面的代碼:

復(fù)制代碼 代碼如下:

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) 運(yùn)行該應(yīng)用程序。稍后就將其關(guān)閉。

(5) 導(dǎo)航到應(yīng)用程序目錄 —— 在目錄中已經(jīng)保存了文件,因?yàn)槲覀兪褂昧讼鄬?duì)路徑。目錄位于WriteFile\bin\Debug文件夾。打開(kāi)Temp.txt文件??梢栽谖募锌吹饺鐖D22-3所示的文本。

FileStream寫(xiě)入數(shù)據(jù)

圖 22-3

示例的說(shuō)明
此應(yīng)用程序在自己的目錄中打開(kāi)文件,并在文件中寫(xiě)入了一個(gè)簡(jiǎn)單的字符串。在結(jié)構(gòu)上這個(gè)示例非常類(lèi)似于前面的示例,只是用Write()代替了Read(),用Encoder代替了Decoder。

下面的代碼行使用String類(lèi)的ToCharArray()靜態(tài)方法,創(chuàng)建了字符數(shù)組。因?yàn)镃#中的所有事物都是對(duì)象,文本“My pink half of the drainpipe.”實(shí)際上是一個(gè)String對(duì)象,所以甚至可以在字符串上調(diào)用這些靜態(tài)方法。

復(fù)制代碼 代碼如下:

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

下面的代碼行顯示了如何將字符數(shù)組轉(zhuǎn)換為FileStream對(duì)象需要的正確字節(jié)數(shù)組。

復(fù)制代碼 代碼如下:

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

這次,要基于UTF8編碼方法來(lái)創(chuàng)建Encoder對(duì)象。也可以將Unicode用于解碼。這里在寫(xiě)入流之前,需要將字符數(shù)據(jù)編碼為正確的字節(jié)格式。在GetBytes()方法中可以完成這些工作,它可以將字符數(shù)組轉(zhuǎn)換為字節(jié)數(shù)組,并將字符數(shù)組作為第一個(gè)參數(shù)(本例中的charData),將該數(shù)組中起始位置的下標(biāo)作為第二個(gè)參數(shù)(0表示數(shù)組的開(kāi)頭)。第三個(gè)參數(shù)是要轉(zhuǎn)換的字符數(shù)量(charData.Length,charData數(shù)組中的元素個(gè)數(shù))。第四個(gè)參數(shù)是在其中置入數(shù)據(jù)的字節(jié)數(shù)組(byData),第五個(gè)參數(shù)是在字節(jié)數(shù)組中開(kāi)始寫(xiě)入位置的下標(biāo)(0表示byData數(shù)組的開(kāi)頭)。

最后一個(gè)參數(shù)決定在結(jié)束后Encoder對(duì)象是否應(yīng)該更新其狀態(tài),即Encoder對(duì)象是否仍然保留它原來(lái)在字節(jié)數(shù)組中的內(nèi)存位置。這有助于以后調(diào)用Encoder對(duì)象,但是當(dāng)只進(jìn)行單一調(diào)用時(shí),這就沒(méi)有什么意義。最后對(duì)Encoder的調(diào)用必須將此參數(shù)設(shè)置為true,以清空其內(nèi)存,釋放對(duì)象,用于垃圾回收。

之后,使用Write()方法向FileStream寫(xiě)入字節(jié)數(shù)組就非常簡(jiǎn)單:

復(fù)制代碼 代碼如下:

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

與Read()方法一樣,Write()方法也有三個(gè)參數(shù):要寫(xiě)入的數(shù)組,開(kāi)始寫(xiě)入的數(shù)組下標(biāo)和要寫(xiě)入的字節(jié)數(shù)。

相關(guān)文章

  • C#讀取文件所有行到數(shù)組的方法

    C#讀取文件所有行到數(shù)組的方法

    這篇文章主要介紹了C#讀取文件所有行到數(shù)組的方法,涉及C#針對(duì)文件及數(shù)組的相關(guān)操作技巧,需要的朋友可以參考下
    2015-07-07
  • 在C#中新手易犯的典型缺陷

    在C#中新手易犯的典型缺陷

    這篇文章的主要內(nèi)容是關(guān)于C#那些新手易犯的典型缺陷,只有對(duì)有可能犯的錯(cuò)誤進(jìn)行總結(jié)才能做得更好,需要的朋友可以參考下
    2015-07-07
  • C#實(shí)現(xiàn)并查集的使用示例

    C#實(shí)現(xiàn)并查集的使用示例

    并查集是一種用于處理一些不相交集合的合并及查詢(xún)問(wèn)題的數(shù)據(jù)結(jié)構(gòu),具有高效、簡(jiǎn)潔、易用的特點(diǎn),本文主要介紹了C#實(shí)現(xiàn)并查集的使用示例,感興趣的可以了解一下
    2023-11-11
  • C#實(shí)現(xiàn)炫酷啟動(dòng)圖-動(dòng)態(tài)進(jìn)度條效果

    C#實(shí)現(xiàn)炫酷啟動(dòng)圖-動(dòng)態(tài)進(jìn)度條效果

    這篇文章主要介紹了基于C#實(shí)現(xiàn)炫酷啟動(dòng)圖-動(dòng)態(tài)進(jìn)度條 效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • C#中is,as,using關(guān)鍵字的使用說(shuō)明

    C#中is,as,using關(guān)鍵字的使用說(shuō)明

    這篇文章主要介紹了C#中is,as,using關(guān)鍵字的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Unity的OnOpenAsset實(shí)用案例深入解析

    Unity的OnOpenAsset實(shí)用案例深入解析

    這篇文章主要為大家介紹了Unity的OnOpenAsset實(shí)用案例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • C#中Hashtable和Dictionary的區(qū)別與用法示例

    C#中Hashtable和Dictionary的區(qū)別與用法示例

    由于 Hashtable 和 Dictionary 同時(shí)存在, 在使用場(chǎng)景上必然存在選擇性, 并不任何時(shí)刻都能相互替代。所以這篇文章主要給大家介紹了關(guān)于C#中Hashtable和Dictionary區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • C#關(guān)機(jī)小程序源碼

    C#關(guān)機(jī)小程序源碼

    這是用所學(xué)習(xí)的C#做的一個(gè)關(guān)機(jī)小程序,功能不多,只是為了練手,需要的朋友可以參考下
    2012-10-10
  • C#靜態(tài)代碼織入AOP組件之Rougamo的使用詳解

    C#靜態(tài)代碼織入AOP組件之Rougamo的使用詳解

    Rougamo是一個(gè)靜態(tài)代碼織入的AOP組件,同為AOP組件較為常用的有Castle、Autofac、AspectCore等,下面就跟隨小編一起來(lái)學(xué)習(xí)一下它的具體使用吧
    2024-01-01
  • c# 從內(nèi)存中釋放Selenium chromedriver.exe

    c# 從內(nèi)存中釋放Selenium chromedriver.exe

    這篇文章主要介紹了c# 從內(nèi)存中釋放Selenium chromedriver.exe的方法,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01

最新評(píng)論

靖宇县| 靖远县| 南安市| 科技| 白河县| 桐梓县| 古蔺县| 凉山| 西畴县| 石河子市| 宜君县| 奎屯市| 南溪县| 泰顺县| 沂水县| 射洪县| 濉溪县| 海晏县| 榕江县| 连州市| 喀喇沁旗| 沾化县| 深圳市| 游戏| 双牌县| 无为县| 成安县| 中方县| 连山| 东乡族自治县| 政和县| 扎鲁特旗| 泸西县| 无棣县| 德阳市| 玉龙| 达拉特旗| 墨竹工卡县| 翁源县| 皋兰县| 门源|