当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 如何有效的使用C#读取文件

ASP.NET
二级域名Cookie问题的解决方法
如何为asp.net网站项目添加子项目
asp.net用url重写URLReWriter实现任意二级域名
asp.net 序列化and反序列化演示
asp.net Timer的使用方法
AjaxControlToolKit DropDownExtender(下拉扩展控件)使用方法
AjaxControlToolKit CalendarExtender(日历扩展控件)的使用方法
让GridView只显示特定用户的数据的方法
让GridView只更新某些特定的数据的方法
ajaxControlToolkit中CascadingDropDown的用法说明
axp.net ScriptManager的简单用法
把程序集安装到全局程序集缓存中的步骤
引用全局程序集缓存内的程序集的方法
asp.net COOKIES需要注意的一点
asp.net UrlReWriter使用经验小结
页面导出为Excel的时间格式的问题
asp.net cookie清除的代码
Asp.net XMLHTTP封装类(GET,Post发送和接收数据)
ASP.NET XmlHttp跨域访问实现代码
Asp.NET 随机码生成基类(随机字母,随机数字,随机字母+数字)

ASP.NET 中的 如何有效的使用C#读取文件


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 242 ::
收藏到网摘: n/a

你平时是怎么读取文件的?使用流读取。是的没错,C#给我们提供了非常强大的类库(又一次吹捧了.NET一番),里面封装了几乎所有我们可以想到的和我们没有想到的类,流是读取文件的一般手段,那么你真的会用它读取文件中的数据了么?真的能读完全么?通常我们读取一个文件使用如下的步骤: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句就可以把文件里面的内容原封不动的读出来,真是太简洁了!可以这段代码真的能像你预期的那样工作么?答案是:几乎可以!在大部分情况下上面的代码工作的很好,但是我们应该注意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); } }} 虽然上面的例子都比较简单,效果也不是很明显(大部分都是对的),也许你早就会了,没关系这篇文章本来就是写给初学者的。下面的方法提供了一种使用指定缓存长度的方式读取流,虽然在很多情况下你可以直接使用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;}