c#读取文件详谈

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句就可以把文件里面的内容原封不动的读出来,真是太简洁了!可以这段代码真的能像你预期的那样工作么?

答案是:几乎可以!在大部分情况下上面的代码工作的很好,但是我们应该注意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;}

(0)

相关推荐

  • C#如何打开并读取usb的文件目录

    下面我通过一个小例子并结合一段代码片段给大家展示下,有需要的朋友可以来借鉴下. 界面上拖一个 button 和treeview  ,运行的时候直接插入优盘,单机按钮就会出现目录文件.不过只能在u盘插入,U盘拔出时,才能接收到信息. 1.[C#]代码 using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; usi

  • C#逐行读取文件的方法

    本文实例讲述了C#逐行读取文件的方法.分享给大家供大家参考.具体如下: 这里使用C#逐行读取文件,对于大文件的读取非常有用. StreamReader sr = new StreamReader("fileName.txt"); string line; while((line= sr.ReadLine()) != null) { Console.WriteLine("xml template:"+line); } if (sr != null)sr.Close()

  • C#读取文件所有行到数组的方法

    本文实例讲述了C#读取文件所有行到数组的方法.分享给大家供大家参考.具体实现方法如下: using System; namespace PlayingAround { class ReadAll { public static void Main(string[] args) { string[] lines = System.IO.File.ReadAllLines(@"C:\t1"); Console.Out.WriteLine("contents = " +

  • C#读取文件MD5值的实现代码

    本文介绍一个C#函数,可以实现计算文件的MD5值,可以用于文件传输后进行有效性校验. 我们知道可以通过将一个字符串进行散列(Hash)运算得到一个32位字符串,将其作为密码来保存是最常见的MD5应用.不知道大家有没有注意到,在网上一些下载文件的地方,旁边注明了MD5校验值,也是一个32位十六制字符串.这个字符串怎么用呢?这就是文件的MD5加密. 当我们将一个文件从网上下载之后 ,可以计算一下文件的MD5值,然后和网上公布的MD5值进行对比.结果一致,表示文件没有问题,如果结果不一致,有两种可能,

  • C#中winform使用相对路径读取文件的方法

    本文实例讲述了C#中winform使用相对路径读取文件的方法.分享给大家供大家参考.具体分析如下: 目录结构如下图所示:   方法一:由于生成的exe文件在bin\debug目录下,可以使用向上查找目录的方式获取要读取的xml文件 复制代码 代码如下: string haarXmlPath = @"../../haarcascade_frontalface_alt_tree.xml"; FileInfo file = new FileInfo(fileName); string  fu

  • C#通过指针读取文件的方法

    本文实例讲述了C#通过指针读取文件的方法.分享给大家供大家参考.具体如下: // readfile.cs // 编译时使用:/unsafe // 参数:readfile.txt // 使用该程序读并显示文本文件. using System; using System.Runtime.InteropServices; using System.Text; class FileReader { const uint GENERIC_READ = 0x80000000; const uint OPEN

  • c#读取文件详谈

    c#里面封装了几乎所有我们可以想到的和我们没有想到的类,流是读取文件的一般手段,那么你真的会用它读取文件中的数据了么?真的能读完全么? 通常我们读取一个文件使用如下的步骤: 1.声明并使用File的OpenRead实例化一个文件流对象,就像下面这样 复制代码 代码如下: FileStream fs = File.OpenRead(filename); 或者 复制代码 代码如下: FileStream fs = FileStream(filename, FileMode.Open, FileAcc

  • Shell逐行读取文件的4种方法

    在Linux中有很多方法逐行读取一个文件的方法,其中最常用的就是下面的脚本里的方法,而且是效率最高,使用最多的方法.为了给大家一个直观的感受,我们将通过生成一个大的文件的方式来检验各种方法的执行效率. 方法1:while循环中执行效率最高,最常用的方法. 复制代码 代码如下: function while_read_LINE_bottm(){ While read LINE do echo $LINE done  < $FILENAME } 注释:我习惯把这种方式叫做read釜底抽薪,因为这种方

  • 利用Shell脚本循环读取文件中每一行的方法详解

    前言 本文主要给大家介绍了关于使用Shell脚本循环读取文件每一行的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.使用for循环 for line in `cat filename` do echo $line done 或者 for line in $(cat filename) do echo $line done 二.使用while循环 while read -r line do echo $line done < filename While循环中rea

  • java读取文件显示进度条的实现方法

    实现这个功能比较简单,用到的类有两个:ProgressMonitorInputStream(主要是整个类) 和 ProgressMonitor ,它们在javax.swing中大体思路,你要首先知道整个文件的大小,和当前已经读取文件的大小,获得整个文件大小的方法 复制代码 代码如下: ProgressMonitorInputStream monitor;/*** @param 表示此进度条要依附在哪个组件上* @param 显示在此进度条上的消息* @param 需要监控的输入流*/monito

  • android按行读取文件内容的几个方法

    一.简单版 复制代码 代码如下: import java.io.FileInputStream; void readFileOnLine(){ String strFileName = "Filename.txt"; FileInputStream fis = openFileInput(strFileName); StringBuffer sBuffer = new StringBuffer(); DataInputStream dataIO = new DataInputStrea

  • Java文件操作之按行读取文件和遍历目录的方法

    按行读取文件 package test; import java.io.*; import java.util.*; public class ReadTest { public static List<String> first_list; public static List<String> second_list; public ReadTest() { first_list = new LinkedList<>(); second_list = new Link

  • 简单的java读取文件示例分享

    可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了 通过这条线路读取甲方的信息:new FileInputStream(file) 目前这个信息已经读进来内存当中了.接下来需要解读成乙方可以理解的东西 既然你使用了FileInputStream().那么对应的需要使用InputStreamReader()这个方法进行解读刚才装进来内存当中的数据 解读完成后要输出呀.那当然要转换成IO可以识别

  • java实现倒序读取文件功能示例分享

    Long end,long num,File file,String charset4个参数说明end 相当于坐标 ,tail 向上的起点,num是读取的行数,file 目标文件 charset字符集 默认UTF8end 为 null 代表从 文件 最末端 向上 获取. Map m=FileUtil.tail(null,10,file,null)//读取文件最后10行,结果在 m.get(FileUtil.ARR) 里FileUtil.tail(m.get(FileUtil.POINT),3,f

  • java按指定编码写入和读取文件内容的类分享

    可以指定编码如:utf-8来写入和读取文件.如果文件编码未知,可以通过该方法先得到文件的编码后再指定正确的编码来读取,否则会出现文件乱码问题. 如何识别文件编码请参考:java自动根据文件内容的编码来读取避免乱码 复制代码 代码如下: package com.zuidaima.util; import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileInputS

随机推荐