今天我们来简单的介绍一下StreamReader,在将StreamReader之前,我们先来了解一下他的父类:TextReader。对于TextReader,大家可能比较陌生,下面我们来看一下TextReader是什么。

一、TextReader

首先让我们来理解一下什么是TextReader,从字面意思入手的话,大家就会恍然大悟了,一个对于Text的读取器,可是又是怎么读取的呢?聪明的你肯定会想到,当然是通过连续的字符进行读取,为什么在介绍StreamReader之前要介绍这个呢?因为他们两个是父子关系,要了解StreamReader最好先了解他的父亲,下面,简单介绍一下TextReader

1、常用属性和方法:

我们可以想象一下Text这个词,在记事本上,中文、英文、各种代码,等等,都是Text,这些文本归根结底是通过一个个的char组成的,所以微软构造出了TextReader这个抽象类对于读取Text的一系列操作,同样对于TextReader我们无法直接实例化,因为他是一个抽象类,只有定义类的行为,不针对特定实现,那我们来看一下TextReader定义了哪些类的行为:

(1)具有一个protected类型的构造函数

(2)void Close() 方法:和上一篇Stream一样,TextReader也有Close方法,在用完之后,记得主动关闭它

(3)void Dispose()方法:释放所有该TextReader所只有的所有资源(注:加入TextReader中持有Stream或其他对象,当TextReader执行了Dispose方法时,Stream对象也被释放了)

(4)int Peek()方法:这个方法主要是寻找当前char的下一个char,当返回值是-1时,表示下个char已经时最后一个位置的char了。

(5)int Read()方法:同样,Read方法是读取下一个char,但是和Peek方法不同,Read方法使指针只想下个字符,但是Peek方法还是指向原来的那个字符

(6)int Read(char[] buffer,int index,int count)方法:这个重载Read方法和上一篇文章中Stream的Read方法有点神似,区别就是一个参数是byte数组,而这个是char数组,(注:是通过Reader将数据读入buffer数组),index从哪个位置开始,count读取char数量。

(7)int ReadBlock(char[] buffer,int index,int count)方法:和Read方法基本一致,区别是从效率上来说ReadBlock更高点,而且ReadBlock并非属于线程安全,使用时要注意。

(8)virtual string ReadLine()方法:顾名思义,这个方法将读取每一行数据并返回当前行的字符的字符串。

(9)virtual string ReadToEnd()方法:包含从当前位置到TextReader的接微的所有字符的字符串

下面,我们就写几个简单的示例来演示一下上面的几个属性和方法。

 string text = "abc\nabc";

             using (TextReader reader = new StringReader(text))
{
while (reader.Peek() != -)
{
Console.WriteLine("Peek = {0}", (char)reader.Peek());
Console.WriteLine("Read = {0}", (char)reader.Read());
}
reader.Close();
} using (TextReader reader = new StringReader(text))
{
char[] charBuffer = new char[];
int data = reader.ReadBlock(charBuffer, , );
for (int i = ; i < charBuffer.Length; i++)
{
Console.WriteLine("通过readBlock读出的数据:{0}", charBuffer[i]);
}
reader.Close();
} using (TextReader reader = new StringReader(text))
{
string lineData = reader.ReadLine();
Console.WriteLine("第一行的数据为:{0}", lineData);
reader.Close();
} using (TextReader reader = new StringReader(text))
{
string allData = reader.ReadToEnd();
Console.WriteLine("全部的数据为:{0}", allData);
reader.Close();
} Console.ReadLine();

 输出结果:

 二、StreamReader

在说明StreamReader之前,还有一件事要提起,那就是多态,多态到底是什么概念呢?聪明的你肯定会想到多态不就是子类的多种表现形式嘛。不错,但这还是不完全的,不仅如此,现实世界中,父亲帮儿子买房子,但是他没有在房产证上写儿子的名字,所以,这个房子儿子和父亲能共同使用,儿子能根据自己的爱好装修房子,父亲也能在儿子装修好的房子内,也就是说父类能够灵活使用子类的功能,更科学的一点就是子类的指针允许(赋值给)父类指针,上述雷子中,TextReader reader=new StringReader(text) 这个就是个多态的经典例子,大家不妨深刻理解下这个更重要的概念。

1、Encoding编码

为什么要简单介绍Encoding编码呢?因为Encoding编码在Stream和相关类中起的非常重要的作用,由于Encoding类会在后续的博文中详细解释,现在我就先介绍下Encoding类的一些重要的编码。

以上边是Encoding类中一些特定的编码,大家先了解即可,但使用Default时有点必须注意,如果你用的不一样编码的机器的时候,注意服务器或其他操作系统的编码规则,举个例子,如果你在一个中文操作系统中进行编码,但是发布到了一个其他语言的操作系统上,那就会出现问题,这时候,你必须选择一个通用的编码。

2、StreamReader类的定义和作用

StreamReader的定义:实现一个TextReader,使其以以重特定的编码从字节流中读取字节。在对于流的操作中,StreamReader对于流的读取方面非常重要,为什么这么说呢?我们常用的文件的复制、移动、上传、下载、压缩、保存、远程FTP文件的读取、甚至于HttpResponse等等只要是于流相关的任何派生类StreamReader都能够轻松处理,当然,大家甚至可以自定义相关的派生类去实现复杂的序列化。在实际项目中,我们可能碰到过许多上述的情况,有时乱码问题会让我们发狂,但是只要深刻去理解计出的话,我相信大家都能找到适合自己的解决方法。

3、StreamReader类的常用属性和方法

其实StreamReader的一些方法已经在父类TextReader中说的很仔细了,但是个人觉得构造函数和属性高才是重点。

构造函数:

(1)StreamReader(Stream stream):将Stream作为一个参数放入StreamReader,这样的话,StreamReader可以对该Stream进行读取操作,Stream对象可以非常广泛,包括所有Stream的派生类对象。

(2)StreamReader(string string,Encoding encoding):这里的string对象不是简单的字符串,而是文件的地址,然后根据用户选择的编码去读取流中的数据。

(3)StreamReader(string string,bool detectEncodingFromByteOrderMarks):有时候我们希望程序自动判断用何种编码去读取,这时候detectEncodingFromByteOrderMarks这个参数就能起这个作用了,当设置为true的时候,通过查看流的前三个字节来检测编码。如果文件以适当的字节顺序标记开头,该参数自动识别UTF-8、Little-Endian Unicode和Big-Endian Unicode文本,当为false时,方法会去使用用户提供的编码。

(4)StreamReader(string string,Encoding encoding,detectEncodingFromByteOrderMarks,int bufferSize):这个方法提供了4个参数的重载,前3个我们都已经了解,最后一个时缓冲区大小的设置。

StreamReader还有其他的一些构造函数,都是上述4个的扩充,大家可以自己看一下。

4、属性:

(1)BaseStream:大家对于前前一章流的操作应该没什么问题,我就直接企切主题,最简单的理解就是将上述构造函数的流对象在重新取出来进行一系列的操作。

可是如果构造函数中是路径怎么办?一样,构造函数能够将路径文件转化成流对象

 FileStream fs = new FileStream ( "D:\\TextReader.txt", FileMode.Open , FileAccess.Read ) ;
StreamReader sr= new StreamReader ( fs ) ;
//本例中的BaseStream就是FileStream
sr.BaseStream.Seek ( , SeekOrigin.Begin ) ;

(2)CurrentEncoding:获取当前StreamReader的Encoding

(3)EndOfStream:判断StreamReader是否已经处于当前流的末尾

好了,下面我们就几个示例来演示一下上述的方法和属性:

 static void Main(string[] args)
{ //文件地址
string txtFilePath="D:\\TextReader.txt";
//定义char数组
char[] charBuffer2 = new char[]; //利用FileStream类将文件文本数据变成流然后放入StreamReader构造函数中
using(FileStream stream = File.OpenRead(txtFilePath))
{
using (StreamReader reader = new StreamReader(stream))
{
//StreamReader.Read()方法
DisplayResultStringByUsingRead(reader);
}
} using (FileStream stream = File.OpenRead(txtFilePath))
{
//使用Encoding.ASCII来尝试下
using (StreamReader reader = new StreamReader(stream,Encoding.ASCII,false))
{
//StreamReader.ReadBlock()方法
DisplayResultStringByUsingReadBlock(reader);
}
} //尝试用文件定位直接得到StreamReader,顺便使用 Encoding.Default
using(StreamReader reader = new StreamReader(txtFilePath, Encoding.Default,false,))
{
//StreamReader.ReadLine()方法
DisplayResultStringByUsingReadLine(reader);
} //也可以通过File.OpenText方法直接获取到StreamReader对象
using (StreamReader reader = File.OpenText(txtFilePath))
{
//StreamReader.ReadLine()方法
DisplayResultStringByUsingReadLine(reader);
} Console.ReadLine();
} /// <summary>
/// 使用StreamReader.Read()方法
/// </summary>
/// <param name="reader"></param>
public static void DisplayResultStringByUsingRead(StreamReader reader)
{
int readChar = ;
string result = string.Empty;
while ((readChar=reader.Read()) != -)
{
result += (char)readChar;
}
Console.WriteLine("使用StreamReader.Read()方法得到Text文件中的数据为 : {0}", result);
} /// <summary>
/// 使用StreamReader.ReadBlock()方法
/// </summary>
/// <param name="reader"></param>
public static void DisplayResultStringByUsingReadBlock(StreamReader reader)
{
char[] charBuffer = new char[];
string result = string.Empty;
reader.ReadBlock(charBuffer,,);
for (int i = ; i < charBuffer.Length; i++)
{
result += charBuffer[i];
}
Console.WriteLine("使用StreamReader.ReadBlock()方法得到Text文件中前10个数据为 : {0}", result);
} /// <summary>
/// 使用StreamReader.ReadLine()方法
/// </summary>
/// <param name="reader"></param>
public static void DisplayResultStringByUsingReadLine(StreamReader reader)
{
int i=;
string resultString = string.Empty;
while ((resultString=reader.ReadLine() )!= null)
{
Console.WriteLine("使用StreamReader.Read()方法得到Text文件中第{1}行的数据为 : {0}", resultString, i);
i++;
} }

 输出结果:

好了,StreamReader的相关知识我们就分享到这里,希望对大家有所帮助。非常感谢 逆时针の风 的博客对我的帮助

关于StreamReader的知识分享的更多相关文章

  1. 分享吉林大学机械科学与工程学院,zhao jun 博士的Halcon学习过程及知识分享

    分享吉林大学机械科学与工程学院,zhao jun 博士的Halcon学习过程及知识分享 全文转载zhao jun 博士的新浪博客,版权为zhaojun博士所有 原文地址:http://blog.sin ...

  2. 使用javascript开发的视差滚动效果的云彩 极客标签 - 做最棒的极客知识分享平台

    www.gbtags.com 使用javascript开发的视差滚动效果的云彩 阅读全文:使用javascript开发的视差滚动效果的云彩 极客标签 - 做最棒的极客知识分享平台

  3. MemoryStream相关知识分享

    一.简单介绍一下MemoryStream MemoryStream是内存流,为系统内存提供读写操作,由于MemoryStream是通过无符号字节数组组成的,可以说MemoryStream的性能可以算比 ...

  4. 制作一个简单的部门员工知识分享的python抽取脚本

    需求: 基于公司的文化和公司部门间以及员工之间的工作需求状态,或者想要了解某一些技能.专业方面的知识需求.促进并提高员工们的技能认知和技术水平. 详细代码如下: 先说一下存入csv表格的表头字段: 1 ...

  5. XML的相关基础知识分享(二)

    前面我们讲了一下XML相关的基础知识(一),下面我们在加深一下,看一下XML高级方面. 一.命名空间 1.命名冲突 XML命名空间提供避免元素冲突的方法. 命名冲突:在XML中,元素名称是由开发者定义 ...

  6. Webfunny知识分享:JS错误监控

    现在的前端开发已不再是刀耕火种的年代了,各种框架.编译工具层出不穷,前端监控系统也不甘其后,遍地开花. 前端正承受着越来越重的职责,前端的业务也变得越来越复杂,此时此刻我们就更需要一套完善的监控系统来 ...

  7. GO基础知识分享

    目录 GO基础知识分享 go语言的基本事项 关键字 字符串的拼接和变量的定义方式 空白符 const常量 iota的用法 运算符 Go 没有三目运算符,不能适用?: 语言条件语句 for循环的方式 函 ...

  8. PureStudy:学科知识分享——个人网站开发全解

    PureStudy:学科知识分享--个人网站开发全解 项目描述 PureStudy,学科知识分享网站. 学生可以使用这个网站,来浏览相应学科的知识点.学习总结,获取相关的资料.此外,他们可以选择上传文 ...

  9. IT人生知识分享:概率与运气

    前言: 最近的人生多了些体验,也读了些许书,感觉还是有些知识是可以分享的. 今天难得周六,特意开电脑了,花几个小时写写,和大伙分享分享点知识. 以下内容,更多的需要读者思考,所以结论不会写太清晰,但一 ...

随机推荐

  1. STL中的unique和unique_copy函数

    一.unique函数 这个函数的功能就是删除相邻的重复元素,然后重新排列输入范围内的元素,并返回一个最后一个无重复值的迭代器(并不改变容器长度). 例如: vector<); ; i < ...

  2. 菜鸟 ssm 框架的学习之路

    跟着老师学习了两个月的java语言,现在学习到了框架的部分,一直想在博客上写点东西的,只是自己一直没有时间,其实到底也是懒,鲁迅说过:"时间就像海绵里的水,只要愿意去挤还是有的", ...

  3. Java第二次作业第一题

    编写图形界面程序,在窗体中设置菜单栏,在菜单栏上添加"file"菜单,在文件菜单中添加"new"和"quit"两个菜单项,其中"q ...

  4. Recovery启动流程(2)---UI界面【转】

    Recovery启动流程系列文章把recvoery目录下文件分成小块讲解,最后再以一条主线贯穿所有的内容.这篇文章主要讲解Recovery-UI的相关内容. 我们知道,当我们通过按键或者应用进入rec ...

  5. jdk1.8源码阅读

    一.java.lang java的基础类 1.object 所有类的爸爸 registerNatives() Class<?> getClass():返回运行时的类 int hashCod ...

  6. 腾讯、阿里、百度、360、114 公共DNS分享

    DNS,在互联网有着重要的地位,域名转换成IP,都是DNS在工作. 腾讯 DNS+ IP:119.29.29.29 备用:182.254.116.116 阿里DNS ip:223.5.5.5 223. ...

  7. Hibernate4之JPA规范配置详解

    @Table Table用来定义entity主表的name,catalog,schema等属性. 属性说明: name:表名 catalog:对应关系数据库中的catalog schema:对应关系数 ...

  8. 使用Spreadsheet导出表格时,设置样式

    $spreadsheet = new Spreadsheet();// 初始化         $spreadsheet->createSheet();// 添加一个sheet          ...

  9. linux&shell学习系列

    1.VMware安装Centos7虚拟机 2.Linux之vim详解 3.linux后台运行的几种方式 4.linux权限管理 5.linux之用户和用户组管理详解 6.grep文本搜索工具详解 7. ...

  10. Mybaits-从零开始-Hello World(暂不考虑命名规范化)

    1.mybatis-config.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...