今天我们来简单的介绍一下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. python+selenium自动化测试——浏览器驱动

    selenium控制浏览器需要下载对应版本的驱动,并把下载好的驱动解压然后拷贝到python的安装目录. 1.chrome 驱动对应版本及下载地址;https://npm.taobao.org/mir ...

  2. mysql生成主键

    在mysql中,可以使用uuid 来生成主键,但是用mysql的uuid()函数 ,生成的uuid是36位的,其中包含32个字符以及4个分隔符(-), 往往这个分隔符对我们来说是没有用的,可以使用my ...

  3. 大数据平台搭建 - cdh5.11.1 - hive客户端安装

    一.简介 hive是基于hadoop的一种数据仓库工具,可以将结构化的文件映射成为数据库的一张表,并提供简单sql查询功能,底层实现是转化为MapReduce任务计算. 二.安装 (1)下载 从cdh ...

  4. sersync 实时同步

    1.什么是实时同步 ​ 监控一个目录的变化, 当该目录触发事件(创建\删除\修改) 就执行动作, 这个动作可以是 rsync同步 ,也可以是其他. 2.为什么要实时同步 1.能解决nfs单点故障问题. ...

  5. 003:CSS三大重点之一:盒子模型

    目录 1:盒子模型 2:边框: 2.1:合写 2.2:适用于:table系元素.边框合并 3:内边距 4:外边距: 4.1:盒子居中三大条件 4.2:外边距合并.外边距塌陷(父子嵌套)解决方法三种 前 ...

  6. [VB.NET Tips]ParamArray参数数组

    ParamArray参数数组,可以理解为传递给方法的多余的参数全都存放在这个数组中. ParamArray只能是ByVal按值传递,不能是可选参数,而且只能做为方法定义的最后一个参数. 非常类似于Py ...

  7. BCD 码、Gray 码、ASCII 码都是什么呢?

    BCD 码:即(Binary Coded Decimal)码,也称为 8421 码,是十进制代码中最常见的一种.每一位的 1 代表的十进制数称为这一位的权.BCD 码中每一位的权都是固定不变的,它属于 ...

  8. spring框架对于实体类复杂属性注入xml文件的配置

    spring框架是javaWeb项目中至关重要的一个框架,大多web 项目在工作层次上分为持久层.服务层.控制层.持久层(dao.mapper)用于连接数据库,完成项目与数据库中数据的传递:服务层(s ...

  9. 【译】Kubernetes监控实践(2):可行监控方案之Prometheus和Sensu

    本文介绍两个可行的K8s监控方案:Prometheus和Sensu.两个方案都能全面提供系统级的监控数据,帮助开发人员跟踪K8s关键组件的性能.定位故障.接收预警. 拓展阅读:Kubernetes监控 ...

  10. JSR303 后端校验包的使用

    1.首先通过Maven导入JSR303架包. <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate- ...