TextReader 和StreamReader
TextReader 和StreamReader
目录:
为什么要介绍 TextReader?
首先让我们来理解下什么是TextReader,从字面上的意思入手的话,大家就会恍然大悟了
一个对于Text的读取器,可是又是怎么读取的呢?聪明的你肯定会想到,当然是通过连续
的字符进行读取, 为什么在介绍StreamReader之前,要搞这个东东? 答案其实很简单:他们
两个就是父子关系,要了解StreamReader最好先了解他的父亲,请允许我对他们进行下简单介绍:
TextReader的常用属性和方法:
我们闭上眼可以想象一下 Text这个词的范围,它囊括了许多的文件类型,我们可以在记事本上
使用任何语言(英语,中文,c# ,天书,JavaScript,jQuery,xml,xaml,sql,c++……),如此多
的语言文本归根结底还是通过一个个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() != -1)
{
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[3];
int data = reader.ReadBlock(charBuffer, 0, 3);
for (int i = 0; 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想到多态
在说明StreamReader之前还有一件事要提起,那就是多态, 多态到底是什么概念呢?聪明的你肯定会想到多态不就是子类的多种
表现形式?不错,但这还是不是完全的,不仅如此,现实世界中,父亲帮儿子买了套房子,但是他没有在房产证上写儿子的名字,
所以这个房子儿子和父亲能共同使用,儿子能根据自己的爱好装修房子,父亲也能住在儿子装修好的房子内,也就是说父类能够
灵活使用子类的功能,更科学的一点就是子类的指针允许(赋值给)父类指针。上述例子中
- TextReader reader = new StringReader(text)
这个就是个多态的经典例子大家不妨深刻理解下这个重要的概念
简单介绍下Encoding编码
为什么要简单介绍Encoding编码?因为Encoding编码在Stream和相关类中起的非常重要的作用,
由于Encoding类会在后续章节详细解释,现在我就先介绍下 Encoding类一些重要编码
以上便是Encoding类中一些特定的编码,大家先了解即可,但使用Default时有点必须注意,如果你用不一样编码的机器的时候,
注意服务器或者其他操作系统的编码规则,举个例子,如果你在一个中文操作系统进行编码,但是发布到了一个其他语言的操作
系统上那就会出问题了这时候你必须选择一个通用编码
StreamReader 类的定义和作用
StreamReader 的定义:实现一个 TextReader,使其以一种特定的编码从字节流中读取字符。
在对于流的操作中,StreamReader对于流的读取方面非常重要,为什么这么说呢,我们常用的文件的复制,移动,上传,下载,压缩,保存,
远程FTP文件的读取,甚至于HttpResponse等等只要是于流相关的任何派生类StreamReader 都能够轻松处理,当然,大家甚至可以自定义
相关的派生类去实现复杂的序列化。在实际项目,我们可能碰到过许多上述的情况,有时乱码的问题会让我们发狂,但是只要深刻去理解基础的话,
我相信大家都能找到适合自己的解决方法
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, bool 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 (0 , SeekOrigin.Begin ) ;
2:CurrentEncoding:
获取当前StreamReader的Encoding
3:EndOfStream:
判断StreamReader是否已经处于当前流的末尾
最后用FileStream的示例来温故下StreamReader

- static void Main(string[] args)
{- //文件地址
string txtFilePath="D:\\TextReader.txt";
//定义char数组
char[] charBuffer2 = new char[3];- //利用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,123))
{
//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 = 0;
string result = string.Empty;
while ((readChar=reader.Read()) != -1)
{
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[10];
string result = string.Empty;
reader.ReadBlock(charBuffer,0,10);
for (int i = 0; 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=1;
string resultString = string.Empty;
while ((resultString=reader.ReadLine() )!= null)
{
Console.WriteLine("使用StreamReader.Read()方法得到Text文件中第{1}行的数据为 : {0}", resultString, i);
i++;
}- }

输出结果:
本章总结
本章详细介绍了TextReader和StreamReader的定义概念和一些注意事项,希望大家能够在本文中温故而知新,下章会简单介绍下TextWriter和StreamWriter
TextReader 和StreamReader的更多相关文章
- C# Stream篇(二) -- TextReader 和StreamReader
TextReader 和StreamReader 目录: 为什么要介绍 TextReader? TextReader的常用属性和方法 TextReader 示例 从StreamReader想到多态 简 ...
- File,FileInfo,FileStream,StreamReader的区别与用法
概括的说,File,FileInfo,FileStream是用于文件 I/O 的类,StreamReader是用于从流读取和写入流的类,使用之前都需using System.IO. 先定义一个TXT文 ...
- C#读操作(字节/字符)Filestream、File、StreamReader
方法一:使用Filestream,将文本一次性全部转换为字节,之后转换为string显示在text中 OpenFileDialog fd = new OpenFileDialog(); fd.Filt ...
- C#各种文件操作的代码与注释
C#各种文件操作的代码与注释,具体看下面代码: using System; using System.Collections.Generic; using System.Linq; using Sys ...
- 基本的文件 I/O
基本的文件 I/O MSDN 抽象基类 Stream 支持读取和写入字节.Stream 集成了异步支持.其默认实现根据其相应的异步方法来定义同步读取和写入,反之亦然. 所有表示流的类都是从 Strea ...
- Stream 流操作
Stream 类 先看下面的图 Stream 是所有流的抽象基类(不能被实例化,需要使用他的派生类FileStream/MemoryStream/BufferedStream).流是字节序列的抽象概 ...
- C# 目录与文件管理
文件读写 学习了一点点希望对以后的学习工作有帮助 在应用程序中基本任务是对数据的操作,这就是对数据进行访问和保存挤兑数据的读写,应用程序访问一个文本文件叫做“读”:对文本文件的内容进行修改后保存这些修 ...
- Stream 基础和常用
来源 : http://www.cnblogs.com/jimmyzheng/archive/2012/03/17/2402814.html 系列 目前只作为个人参考. 微软的 stream 结构老大 ...
- 在 ASP.NET Core 中执行租户服务
在 ASP.NET Core 中执行租户服务 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: http://gunna ...
随机推荐
- linux 下 docker-compose安装
docker和dockers-compose的版本兼容对照 以下是我的服务器的相关信息 linux版本 [root@izbp16fm097gaw3tdaog2wz bin]# cat /proc/ve ...
- 如何用纯 CSS 创作一个小球反弹的动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OwWROO 可交互视频 ...
- vue使用原生js实现滚动页面跟踪导航高亮
需要使用vue做一个专题页面. 滚动页面指定区域导航高亮. BetterScroll:可能是目前最好用的移动端滚动插件 如何自定义CSS滚动条的样式? 监听滚动页面事件,对比当前页面的位置与元素的位置 ...
- Python学习笔记:字符串
字符串 字符串定义:字符串可以使用一对单引号.双引号或三引号来定义,即便是单个字符也会当做字符串来处理(Python中没有字符类型,单个字符也就是只有一个字符的字符串而已). 原始字符串:字符串中反斜 ...
- R-barplot()
barplot这个函数啊...坑...度娘的很多解决方案都不对,只好重新看回manual再做测试== 本文参考的是: https://stat.ethz.ch/R-manual/R-devel/lib ...
- ACM-ICPC 2018 徐州赛区网络预赛 B. BE, GE or NE
In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named &qu ...
- C语言指针分析
/*************1*************/ int p; //p是一个普通的整型变量. /*************2*************/ int *p; //p与*结合,说明 ...
- python基础学习笔记——字符串方法
索引和切片: 索引:取出数组s中第3个元素:x=s[2] 切片:用极少的代码将数组元素按需处理的一种方法.切片最少有1个参数,最多有3个参数,演示如下: 我们假设下面所用的数组声明为array=[2, ...
- ASP.Net教程系列:多线程编程实战(一)
Web开发中使用多线程可以增强用户体验,尤其是多用户.多任务.海量数据和资源紧张的情况下.所以我们的ASP.Net教程设立多线程编程实战专题.下面这些代码范例都是入门级的,希望对对大家学习ASP.Ne ...
- Java项目引入eclipse注意事项
我以前也搞过java,后转前端,接触html+css+js时间比较多,所以java后端也忘了差不多.最近负责公司的邮件系统项目,项目是java语言写,项目架构比较复杂,在部署项目的时候,遇到了很多问题 ...