C#中流的读取器和编写器(BinaryReader与 BinaryWriter ,StreamReader 与 StreamWriter,StringReader 等)详细介绍

C#中流的读取器和编写器(BinaryReader与 BinaryWriter ,StreamReader 与 StreamWriter,StringReader 等)详细介绍
硕士研究生在读,分享编程、人工智能、智能建造、学习和科研经验
C#进阶笔记系列,帮助您强化C#基础,资料整理不易,欢迎关注交流!
通常,流用于字节输入和输出。 读取器和编写器类型处理编码字符与字节之间的来回转换,以便流可以完成操作。
下面是一些常用的读取器和编写器类:
- BinaryReader和 BinaryWriter :用于将基元数据类型作为二进制值进行读取和写入。
- StreamReader 和 StreamWriter : 用于通过使用编码值在字符和字节之间来回转换来读取和写入字符。
- StringReader 和 StringWriter:用于从字符串读取字符以及将字符写入字符串中。
- TextReader和 TextWriter :用作其他读取器和编写器(读取和写入字符和字符串,而不是二进制数据)的抽象基类。
1 先了解一下字符与字节
字节(Byte)是计量单位,表示数据量多少,是计算机信息技术用于计量存储容量的一种计量单位,通常情况下一字节(Byte)等于八位(bit)。
字符(Character)计算机中使用的字母、数字、字和符号,比如'A'、'B'、'$'、'&'等。
一般在英文状态下一个字母或字符占用一个字节,一个汉字用两个字节表示。

字节与字符:
- ASCII 码中,一个英文字母(不分大小写)为一个字节,一个中文汉字为两个字节。
- UTF-8 编码中,一个英文字为一个字节,一个中文为三个字节。
- Unicode 编码中,一个英文为一个字节,一个中文为两个字节。
- 符号:英文标点为一个字节,中文标点为两个字节。例如:英文句号 . 占1个字节的大小,中文句号 。占2个字节的大小。
- UTF-16 编码中,一个英文字母字符或一个汉字字符存储都需要 2 个字节(Unicode 扩展区的一些汉字存储需要 4 个字节)。
- UTF-32 编码中,世界上任何字符的存储都需要 4 个字节。
2 BinaryReader 和BinaryWriter
2.1 BinaryReader
用特定的编码将基元数据类型读作二进制值。
2.1.1 常用构造方法和方法
构造方法和方法 | 描述 |
BinaryReader(Stream, Encoding, Boolean) | 基于所提供的流和特定的字符编码,初始化 BinaryReader 类的新实例,有选择性的打开流。Boolean:如果在释放 BinaryReader对象后保持流处于打开状态,则为 true;否则为 false。 |
Close() | 关闭当前阅读器及基础流 |
Dispose(Boolean) | 释放 BinaryReader类使用的非托管资源,并可以选择释放托管资源。 |
PeekChar() | 返回下一个可用的字符,并且不提升字节或字符的位置。如果没有可用字符或者流不支持查找时为 -1 |
Read() | 从基础流中读取字符,并根据所使用的 Encoding 和从流中读取的特定字符,提升流的当前位置。 |
Read(Span) | 从当前流读取字节序列,并将流中的位置向前移动读取的字节数。 |
ReadChar(int32) | 从当前流中读取指定的字符数,并以字符数组的形式返回数据,然后根据所使用的 Encoding 和从流中读取的特定字符,将当前位置前移。int32:要读取的字符数。 |
ReadString() | 从当前流中读取一个字符串。 字符串有长度前缀,一次 7 位地被编码为整数。 |
ReadBytes(Int32) | 从当前流中读取指定的字节数以写入字节数组中,并将当前位置前移相应的字节数。 |
BaseStream | 获取 BinaryWriter 的基础流。 |
2.1.2代码示例
using System;
using System.IO;
using System.Text;
class ConsoleApplication
{
const string fileName = "AppSettings.dat";
static void Main()
{
WriteDefaultValues();
DisplayValues();
}
public static void WriteDefaultValues()//写入默认值的方法
{//打开文件
using (var stream = File.Open(fileName, FileMode.Create))
{//新建一个输入流,并以UTF-8编码,释放BinaryWriter后关闭流
using (var writer = new BinaryWriter(stream, Encoding.UTF8, false))
{//写入数据
writer.Write(1.250F);
writer.Write(3.657F);
writer.Write(@"c:\Temp");
writer.Write(10);
writer.Write(true);
}
}
}
public static void DisplayValues()//读取数据
{
float aspectRatio1;
float aspectRatio2;
string tempDirectory;
int autoSaveTime;
bool showStatusBar;
if (File.Exists(fileName))//如果文件存在
{//打开文件
using (var stream = File.Open(fileName, FileMode.Open))
{//读取文件流
using (var reader = new BinaryReader(stream, Encoding.UTF8, false))
{
aspectRatio1 = reader.ReadSingle();//从当前流中读取 4 字节浮点值
aspectRatio2 = reader.ReadSingle();//从当前流中读取 4 字节浮点值
tempDirectory = reader.ReadString();//从当前流中读取一个字符串。
autoSaveTime = reader.ReadInt32();
showStatusBar = reader.ReadBoolean();
}
}
Console.WriteLine("Aspect ratio1 set to: " + aspectRatio1);
Console.WriteLine("Aspect ratio2 set to: " + aspectRatio2);
Console.WriteLine("Temp directory is: " + tempDirectory);