今天我们来简单的介绍一下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. 【Rocketmq】通过 docker 快速搭建 rocketmq 环境

    1. 安装 Namesrv 拉取镜像 docker pull rocketmqinc/rocketmq:4.4.0` 启动容器 docker run -d -p 9876:9876 -v {RmHom ...

  2. ubuntu系统设置开机后使用使用终端运行应用程序

    1.在菜单栏输入start,点击startup application进入 2. 添加开机启动程序 3.因为要用终端启动一个应用程序,所以command输入:gnome-terminal -- 程序执 ...

  3. day 12 特殊权限

    1.suid (set uid) 特殊权限 suid优点: 可以让普通用户执行无法执行的命令 方便 suid缺点: 如果rm 为suid, 无论谁执行该命令,都能删除系统的任何 资源 set uid ...

  4. Webpack 打包太慢? 试试 Dllplugin

    webpack在build包的时候,有时候会遇到打包时间很长的问题,这里提供了一个解决方案,让打包如丝般顺滑~ 1. 介绍 在用 Webpack 打包的时候,对于一些不经常更新的第三方库,比如 rea ...

  5. SpringBoot区块链之以太坊区块高度扫描(简洁版)

    继续昨天的demo往下写写:[SpringBoot区块链之以太坊开发(整合Web3j)](https://juejin.im/post/5d88e6c1518825094f69e887),将复杂的逻辑 ...

  6. 品Spring:SpringBoot发起bean定义注册的“二次攻坚战”

    上一篇文章整体非常轻松,因为在容器启动前,只注册了一个bean定义,就是SpringBoot的主类. OK,今天接着从容器的启动入手,找出剩余所有的bean定义的注册过程. 具体细节肯定会颇为复杂,同 ...

  7. 4款黑科技级别的宝藏APP,能够轻松满足你的多种需求,请低调收藏

    有没有这样几款软件,在你每次一换新手机的时候就会立刻重新安装下来,感觉自己已经完全离不开它们?今天就来给大家分享几个非常好用的APP. 一.小羊搜搜 在生活中人人都有自己的爱好,无论你是喜欢影视.小说 ...

  8. 23种设计模式之装饰器模式(Decorator Pattern)

    装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...

  9. Spring 梳理-bean配置与装配

    1       bean配置与装配 1.1      bean在XML文件中进行显示配置并装配 1.2      bean在JavaConfig中显示配置并装配 1.2.1  优点:类型是安全的,编译 ...

  10. PHP 正则表达式的简单应用以 preg_match_all 抓取HTML元素为例 [转载]

    PHP 正则表达式的简单应用以 preg_match_all 抓取HTML元素为例 2011-12-02 17:09:39|  分类: PHP|举报|字号 订阅     下载LOFTER我的照片书   ...