前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈StreamReader类

浅谈StreamReader类

作者头像
小蜜蜂
发布2019-07-15 16:09:12
5760
发布2019-07-15 16:09:12
举报
文章被收录于专栏:明丰随笔明丰随笔

根据之前的文章可以知道,stream的世界里全是二进制。二进制数据可以在网络中传输,可以存储在计算机中。在冰冷的计算机的世界里,它们只能处理二进制数据。

但是作为人类而言,是没有办法阅读和理解二进制数据的。人类所能理解是人类的文字,比如中国人可以理解中文;美国人可以理解英文;日本人可以理解日文。

人类文字的最小单位是字符。比如:

中文的:你,我,他 。。。

英文的:a,b,c...

它们都是一个一个的字符,通过把这些字符连接起来,我们就可能创作出优美的诗词和文章。

所以计算机和人类之间有一道鸿沟,我们需要在二进制和人类文字之间建立一座桥梁,它就是Encoding技术。

因为最早计算机是美国人发明的,所以当时推出来的ASCII字符集只支持英文。后来计算机在全球范围迅速发展,ASCII字符集不能支持其他国家的语言,最后推出来了UTF8字符集,它支持所有的人类语言。

我们使用UTF8字符集对字符串和二进制进行互相转换:

代码语言:javascript
复制
//string to byte[]
Encoding.UTF8.GetBytes(str);
//byte[] to string
Encoding.UTF8.GetString(bytes);

在.Net Framework中,Encoding定义了很多种转换方法,我根据源码列出几个典型方法:

代码语言:javascript
复制
byte[] GetBytes(char[] chars);
byte[] GetBytes(string s);
char[] GetChars(byte[] bytes);
string GetString(byte[] bytes);

我们可以通过这几个方法,就可以在二进制和人类文字之间自由穿梭。

在C#中,char[]和string之间的转换如下:

代码语言:javascript
复制
//string to char[]
string ss = "abcdefg";
char[] cc = ss.ToCharArray();
//char[] to string
string str = new string(cc);

好,文章到这里已经完成了必要的铺垫,下面请文章的绝对主角粉墨登场:StreamReader类。

代码语言:javascript
复制
public class StreamReader : TextReader { ... }

StreamReader类扩展了TextReader抽象类,TextReader是StreamReader的父类。TextReader类的背后是char[],TextReader类封装了char[], 并提供了一些方法,用于处理内部的char[]。

在TextReader类中的方法:

代码语言:javascript
复制
//读取当前char的下一个char,当返回值是-1时,表示下个char已经是最后一个位置的char了
int Peek();
//读取当前char的下一个char,但是和peek方法不同,Read()方法使指针指向下个字符,但是Peek还是指向原来那个字符
int Read();
//读取TextReader内部的char[]数据到buffer中,index是char[] buffer的起始位置,count是保存的数量
int Read(char[] buffer, int index, int count);
//读取指针行的数据并返回字符串,指针移到下一行,返回null,表示数据全部读取完了
string ReadLine();
//指针当前位置到结尾的所有字符的字符串
string ReadToEnd();
//用完之后应该主动关闭
void Close();
void Dispose();

因为TextReader是抽象类,所以我们使用StringReader来对TextReader进行简单的练习:

代码语言:javascript
复制
string text = "abc\nabc";
using (TextReader reader = new StringReader(text))
{
  while (reader.Peek() != -1)
  {
    Console.WriteLine("Read = {0}", (char)reader.Read());
  }
}

using (TextReader reader = new StringReader(text))
{
  char[] buffer = new char[3];
  int data = reader.Read(buffer, 0, 3);
  for (int i = 0; i < buffer.Length; i++)
  {
    Console.WriteLine("通过Read读出的数据:{0}", buffer[i]);
  }
}

using (TextReader reader = new StringReader(text))
{
  string lineData = reader.ReadLine();
  Console.WriteLine("第一行的数据为:{0}", lineData);
}

using (TextReader reader = new StringReader(text))
{
  string allData = reader.ReadToEnd();
  Console.WriteLine("全部的数据为:{0}", allData);
}

好,文章到这里我们学习了StreamReader的父类TextReader,那StreamReader在TextReader的基础上,它又提供了哪些能力呢?

其实StreamReader类存在的意义是封装了从流到字符串的转换。封装了从二进制到人类文字的升华。我们看一下它的构造函数:

代码语言:javascript
复制
StreamReader(Stream stream);
StreamReader(Stream stream, Encoding encoding);
StreamReader(string path);
StreamReader(string path, Encoding encoding);

通过上面的构造函数,我们总结一下:

1. 可以传入一个Stream对象,完成StreamReader的初始化。

这种方式很巧妙,在之前的文章里面,我们知道.Net Framework中已经定义了很多种的Stream,例如MemoryStream,FileStream,BufferedStream等等,但是StreamReader提供了一个统一的方式来处理流,并不关心流的对象到底是MemoryStream还是FileStream类型的。

2. 可以选择传入一个Encoding对象,不传的话,默认是Encoding.UTF8。

3. 可以传入一个文件路径,这样文件内容,就会以流的形式加载到内存中。

属性:

代码语言:javascript
复制
//获取当前的stream对象
Stream BaseStream;
//获取当前StreamReader的Encoding
Encoding CurrentEncoding;
//判断StreamReader是否已经处于当前流的末尾
bool EndOfStream;

最后我们练习一下StreamReader类:

代码语言:javascript
复制
string txtFilePath="D:\\TextReader.txt";
//利用FileStream类将文件文本数据变成流然后放入StreamReader构造函数中
using(FileStream stream = File.OpenRead(txtFilePath))
{
  using (StreamReader reader = new StreamReader(stream))
  {
    DisplayResultStringByUsingRead(reader);
  }
}
using (FileStream stream = File.OpenRead(txtFilePath))
{
  using (StreamReader reader = new StreamReader(stream, false))
  {
    DisplayResultStringByUsingRead(reader);
  }
}
//也可以通过File.OpenText方法直接获取到StreamReader对象
using (StreamReader reader = File.OpenText(txtFilePath)) 
{
  DisplayResultStringByUsingRead(reader);
}
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);
}

文章到了这里,已经接近尾声,加上一句比较有哲理的句子,为这篇文章画上一个句号:

一个人,只有当他的灵魂真正撼动了、刺痛了,他的智慧才可能被空前的发掘。人一旦变得清醒、理智起来,他就一步步靠近了成熟。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 明丰随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档