通常我們讀取一個文件使用如下的步驟:
1、聲明並使用File的OpenRead實例化一個文件流對象,就像下面這樣
2、准備一個存放文件內容的字節數組,fs.Length將得到文件的實際大小,就像下面這樣
3、開始讀了,調用一個文件流的一個方法讀取數據到data數組中
FileStream fs = File.OpenRead(filename); 或者
FileStream fs = FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] data = new byte[fs.Length];
fs.Read (data, 0, data.Length);
下面的方法提供了一個比上面方法更安全的方法,來保證文件被完全讀出
public static void SafeRead (Stream stream, byte[] data)
{
int offset=0;
int remaining = data.Length; // 只要有剩余的字節就不停的讀
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException("文件讀取到"+read.ToString()+"失敗!"); // 減少剩余的字節數
remaining -= read; // 增加偏移量
offset += read;
}
}
有些情況下你不知道流實際的長度,比如:網絡流。此時可以使用類似的方法讀取流直到流裡面的數據完全讀取出來為止。我們可以先初始化一段緩存,再將流讀出來的流信息寫到內存流裡面,就像下面這樣:
public static byte[] ReadFully (Stream stream)
{
// 初始化一個32k的緩存
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream())
{
//返回結果後會自動回收調用該對象的Dispose方法釋放內存 // 不停的讀取
while (true)
{
int read = stream.Read (buffer, 0, buffer.Length); // 直到讀取完最後的3M數據就可以返回結果了
if (read <= 0)
return ms.ToArray(); ms.Write (buffer, 0, read);
}
}
}
雖然上面的例子都比較簡單,效果也不是很明顯(大部分都是對的),也許你早就會了,沒關系這篇文章本來就是寫給初學者的。 下面的方法提供了一種使用指定緩存長度的方式讀取流,雖然在很多情況下你可以直接使用Stream.Length得到流的長度,但是不是所有的流都可以得到。
public static byte[] Read2Buffer (Stream stream, int BufferLen)
{
// 如果指定的無效長度的緩沖區,則指定一個默認的長度作為緩存大小
if (BufferLen < 1)
{ BufferLen = 0x8000; } // 初始化一個緩存區
byte[] buffer = new byte[BufferLen];
int read=0; int block; // 每次從流中讀取緩存大小的數據,知道讀取完所有的流為止
while ( (block = stream.Read(buffer, read, buffer.Length-read)) > 0)
{
// 重新設定讀取位置
read += block; // 檢查是否到達了緩存的邊界,檢查是否還有可以讀取的信息
if (read == buffer.Length)
{
// 嘗試讀取一個字節
int nextByte = stream.ReadByte(); // 讀取失敗則說明讀取完成可以返回結果
if (nextByte==-1)
{
return buffer;
} // 調整數組大小准備繼續讀取
byte[] newBuf = new byte[buffer.Length*2]; Array.Copy(buffer, newBuf, buffer.Length);
newBuf[read]=(byte)nextByte; buffer = newBuf;
// buffer是一個引用(指針),這裡意在重新設定buffer指針指向一個更大的內存
read++;
}
} // 如果緩存太大則使用ret來收縮前面while讀取的buffer,然後直接返回
byte[] ret = new byte[read]; Array.Copy(buffer, ret, read);
return ret;
}
using System;
using System.IO;
using System.Collections;
namespace TextFileReader_csharp
{
class Class1
{
static void Main(string[] args)
{
StreamReader objReader = new StreamReader("c:\test.txt");
string sLine="";
ArrayList arrText = new ArrayList();
while (sLine != null)
{
sLine = objReader.ReadLine();
if (sLine != null)
arrText.Add(sLine);
}
objReader.Close();
foreach (string sOutput in arrText