日期:2014-05-18 浏览次数:20886 次
?
通常我们使用C#读取文件信息使用如下的步骤:
1、声明并使用File的OpenRead实例化一个文件流对象,就像下面这样
FileStream fs = File.OpenRead(filename);
或者
FileStream fs = FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
2、准备一个存放文件内容的字节数组,fs.Length将得到文件的实际大小,就像下面这样
byte[] data = new byte[fs.Length];
3、开始读了,调用一个文件流的一个方法读取数据到data数组中
fs.Read (data, 0, data.Length);
我们只写了3句就可以用C#读取文件信息,而且里面的内容原封不动的读出来,真是太简洁了,在大部分情况下上面的代码工作的很好,但是我们应该注意Read方法是有返回值的,既然有返回值那么一定有其道理,如果按照上面的写法完全可以是一个没有返回值的函数。我想返回值的目的是,为了给我们一个机会判断实际读取文件的大小,从而来判断文件是否已经完全读完。所以上面的代码不能保证我们一定读完了文件里面的所有字节(虽然在很多情况下是读完了)。下面的方法提供了一个比上面方法更安全的方法,来保证文件被完全读出。
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); ?