本篇內(nèi)容介紹了“C#讀取文件的方法”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
目前創(chuàng)新互聯(lián)已為數(shù)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、海陵網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
C#讀取文件高效方法問題的提出:你平時是怎么讀取文件的?使用流讀取。是的沒錯,C#給我們提供了非常強(qiáng)大的類庫(又一次吹捧了.NET一番),里面封裝了幾乎所有我們可以想到的和我們沒有想到的類,流是讀取文件的一般手段,那么你真的會用它讀取文件中的數(shù)據(jù)了么?真的能讀完全么?
通常我們使用C#讀取文件使用如下的步驟:
1、聲明并使用File的OpenRead實(shí)例化一個文件流對象,就像下面這樣
FileStream fs = File.OpenRead(filename);
或者
FileStream fs = FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
2、準(zhǔn)備一個存放文件內(nèi)容的字節(jié)數(shù)組,fs.Length將得到文件的實(shí)際大小,就像下面這樣
byte[] data = new byte[fs.Length];
3、哇!開始讀了,調(diào)用一個文件流的一個方法讀取數(shù)據(jù)到data數(shù)組中
fs.Read (data, 0, data.Length);
C#讀取文件的驚奇發(fā)現(xiàn):呵呵!我們只寫了3句就可以把文件里面的內(nèi)容原封不動的讀出來,真是太簡潔了!可以這段代碼真的能像你預(yù)期的那樣工作么?答案是:幾乎可以!在大部分情況下上面的代碼工作的很好,但是我們應(yīng)該注意Read方法是有返回值的,既然有返回值那么一定有其道理,如果按照上面的寫法完全可以是一個沒有返回值的函數(shù)。我想返回值的目的是,為了給我們一個機(jī)會判斷實(shí)際讀取文件的大小,從而來判斷文件是否已經(jīng)完全讀完。所以上面的代碼不能保證我們一定讀完了文件里面的所有字節(jié)(雖然在很多情況下是讀完了)。下面的方法提供了一個比上面方法更安全的方法,來保證文件被完全讀出
public static void SafeRead (Stream stream, byte[] data){ int offset=0; int remaining = data.Length; // C#讀取文件之只要有剩余的字節(jié)就不停的讀 while (remaining > 0){ int read = stream.Read(data, offset, remaining); if (read <= 0) throw new EndOfStreamException("文件讀取到"+read.ToString()+"失?。?); // C#讀取文件之減少剩余的字節(jié)數(shù) remaining -= read; // C#讀取文件之增加偏移量 offset += read; } }
C#讀取文件會遇見的問題:有些情況下你不知道流實(shí)際的長度比如:網(wǎng)絡(luò)流。此時可以使用類似的方法讀取流直到流里面的數(shù)據(jù)完全讀取出來為止。我們可以先初始化一段緩存,再將流讀出來的流信息寫到內(nèi)存流里面,就像下面這樣:
public static byte[] ReadFully (Stream stream){ // 初始化一個32k的緩存 byte[] buffer = new byte[32768]; using (MemoryStream ms = new MemoryStream()){ //返回結(jié)果后會自動回收調(diào)用該對象的Dispose方法釋放內(nèi)存 // 不停的讀取 while (true){ int read = stream.Read (buffer, 0, buffer.Length); // 直到讀取完***的3M數(shù)據(jù)就可以返回結(jié)果了 if (read <= 0) return ms.ToArray(); ms.Write (buffer, 0, read); } } }
雖然上面的例子都比較簡單,效果也不是很明顯(大部分都是對的),也許你早就會了,沒關(guān)系這篇文章本來就是寫給初學(xué)者的。
下面的方法提供了一種使用指定緩存長度的方式讀取流,雖然在很多情況下你可以直接使用Stream.Length得到流的長度,但是不是所有的流都可以得到。
public static byte[] Read2Buffer (Stream stream, int BufferLen){ // 如果指定的無效長度的緩沖區(qū),則指定一個默認(rèn)的長度作為緩存大小 if (BufferLen < 1){ BufferLen = 0x8000; } // 初始化一個緩存區(qū) byte[] buffer = new byte[BufferLen]; int read=0; int block; // 每次從流中讀取緩存大小的數(shù)據(jù),知道讀取完所有的流為止 while ( (block = stream.Read(buffer, read, buffer.Length-read)) > 0){ // C#讀取文件之重新設(shè)定讀取位置 read += block; // C#讀取文件之檢查是否到達(dá)了緩存的邊界,檢查是否還有可以讀取的信息 if (read == buffer.Length){ // 嘗試讀取一個字節(jié) int nextByte = stream.ReadByte(); // C#讀取文件之讀取失敗則說明讀取完成可以返回結(jié)果 if (nextByte==-1){ return buffer; } // 調(diào)整數(shù)組大小準(zhǔn)備繼續(xù)讀取 byte[] newBuf = new byte[buffer.Length*2]; Array.Copy(buffer, newBuf, buffer.Length); newBuf[read]=(byte)nextByte; buffer = newBuf; // buffer是一個引用(指針), //這里意在重新設(shè)定buffer指針指向一個更大的內(nèi)存 read++; } } // 如果緩存太大則使用ret來收縮前面while讀取的buffer,然后直接返回 byte[] ret = new byte[read]; Array.Copy(buffer, ret, read); return ret; }
“C#讀取文件的方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!