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

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

时间:2022-09-01 19:13:13浏览次数:126  
标签:StreamWriter 字节 字符 C# 写入 WriteLine StreamReader 读取器 读取

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);
            Console.WriteLine("Auto save time set to: " + autoSaveTime);
            Console.WriteLine("Show status bar: " + showStatusBar);
        }
    }
}

运行结果

Aspect ratio1 set to: 1.25
Aspect ratio2 set to: 3.657
Temp directory is: c:\Temp
Auto save time set to: 10
Show status bar: True

2.2 BinaryWriter

将二进制中的基元类型写入流并支持用特定的编码写入字符串。

2.2.1 常用构造方法和方法

构造方法和方法 描述
BinaryWriter(Stream, Encoding, Boolean) 基于所提供的流和特定的字符编码,初始化 BinaryWriter 类的新实例,有选择性的打开流。Boolean:如果在释放 BinaryReader对象后保持流处于打开状态,则为 true;否则为 false。
Close() 关闭当前阅读器及基础流
Dispose(Boolean) 释放 BinaryWriter类使用的非托管资源,并可以选择释放托管资源。
Flush() 清理当前编写器的所有缓冲区,使所有缓冲数据写入基础设备。
Seek(Int32, SeekOrigin) 设置当前流中的位置。
Write(Double) 将 8 字节浮点值写入当前流,并将流的位置提升 8 个字节。
Write(String) 将有长度前缀的字符串按 BinaryWriter 的当前编码写入此流,并根据所使用的编码和写入流的特定字符,提升流的当前位置。
Write(Char[], Int32, Int32) 将字符数组部分写入当前流,并根据所使用的 Encoding(可能还根据向流中写入的特定字符),提升流的当前位置。Char[]:包含要写入的数据的字符数组。第一个Int32:要从 chars 中读取且要写入流的第一个字符的索引。第二个int32:要从 chars 中读取且要写入流的字符数。
Write(Byte[], Int32, Int32) 将字节数组区域写入当前流。
Write(Boolean) 将单字节 Boolean 值写入当前流,其中 0 表示 false,1 表示 true。

2.2.2代码示例

 static void Main()
    {
        char[] nemechar = "智能建造小硕".ToCharArray();
        MemoryStream memStream = new MemoryStream();
        BinaryWriter binWriter = new BinaryWriter(memStream);
        //写入内存
        binWriter.Write("微信公众号的名字为: ");
        binWriter.Write( nemechar, 0, nemechar.Length);
        //读取内存
        BinaryReader binReader = new BinaryReader(memStream);
        // 设置当前MemoryStream的开始指针
        memStream.Position = 0;
        // 在控制打印出来
        Console.Write(binReader.ReadString());
        int arraySize = (int)(memStream.Length - memStream.Position);        
        char[] memoryData = new char[arraySize];
        binReader.Read(memoryData, 0, arraySize);
        Console.WriteLine(memoryData);
        Console.WriteLine("名字长度"+memStream.Length);
        Console.WriteLine("读取完后指针的当前位置"+memStream.Position);
        binWriter.Close();
        binReader.Close();
        Console.WriteLine("".PadLeft(40,'-'));
        const int arrayLength = 1000;
        byte[] dataArray = new byte[arrayLength];
        byte[] verifyArray = new byte[arrayLength];
        new Random().NextBytes(dataArray);//随机产生字节数组
        using (BinaryWriter binWriter1 = new BinaryWriter(new MemoryStream()))
        {
            Console.WriteLine("写入数据");
            binWriter1.Write(dataArray, 0, arrayLength);
            using (BinaryReader binReader1 = new BinaryReader(binWriter1.BaseStream))
            //BaseStream就是操作streamreader的,返回的结果就是streamreader
            {
                binReader1.BaseStream.Position = 0;
                if (binReader1.Read(verifyArray, 0, arrayLength) != arrayLength)//写入先后数据的长度是否相等
                {
                    Console.WriteLine("错误写入数据");
                    return;//退出运行
                }
            }
        }
        for (int i = 0; i < arrayLength; i++)
        {//读取前后的两个数据是否一样
            if (verifyArray[i] != dataArray[i])
            {
                Console.WriteLine("错误写入数据");
                return;
            }
        }
        Console.WriteLine("数据被写入并验证");
    }

运行结果:

微信公众号的名字为: 智能建造小硕
名字长度48
读取完后指针的当前位置48
----------------------------------------
写入数据
数据被写入并验证

3 StreamReader 和 StreamWriter

3.1 StreamReader

实现一个 TextReader,使其以一种特定的编码从字节流中读取字符。

StreamReader 默认为 UTF-8 编码,除非另有指定,而不是默认为当前系统的 ANSI 代码页。 UTF-8 正确处理 Unicode 字符,并针对操作系统的本地化版本提供一致的结果。

3.1.1 常用属性和方法

构造方法和方法 描述
StreamReader(Stream, Encoding, Boolean, Int32, Boolean) 为指定的流初始化 StreamReader 类的新实例,带有指定的字符编码、字节顺序标记检测选项和缓冲区大小,有选择性的打开流。Boolean:如果要在文件开头查找字节顺序标记,则为true ;否则为 false。Int32:最小缓冲区大小。Boolean:如果在释放 StreamReader对象后保持流处于打开状态,则为 true;否则为 false。
StreamReader(String, Encoding, Boolean, Int32) 为指定的文件名初始化 StreamReader类的新实例,带有指定字符编码、字节顺序标记检测选项和缓冲区大小。
BaseStream 返回基础流。
CurrentEncoding 获取当前 StreamReader对象正在使用的当前字符编码。
Close() 关闭 StreamReader对象和基础流,并释放与读取器关联的所有系统资源。
Read(Char[], Int32, Int32) 从指定的索引位置开始将来自当前流的指定的最多字符读到缓冲区。第一个Int32;开始写入的 buffer 的索引。第二个Int32:最多读取的字符数。
ReadLine() 从当前流中读取一行字符并将数据作为字符串返回。
Dispose() 释放由 TextReader对象使用的所有资源。
ReadToEnd() 读取来自流的当前位置到结尾的所有字符。

3.1.2 代码示例

 public static void Main()
    {
        try
        { //创建一个StreamReader实例读取文件
            using (StreamReader sr = new StreamReader("G:\\Desktop\\archive1\\MyTest.txt"))
            {
                string line;
                //一行行读取文件并在控制台输出
                while ((line = sr.ReadLine()) != null)
                {
                    Console.WriteLine(line);
                }
            }
            MemoryStream ms =  new MemoryStream();
            StreamWriter streamWriter = new StreamWriter(ms);           
            streamWriter.Write("智能建造小硕\n");    
            streamWriter.Flush();
            ms.Position = 0;
            StreamReader streamReader = new StreamReader(ms);
            Console.WriteLine(streamReader.EndOfStream);
            String rs =streamReader.ReadLine();
            Console.WriteLine(rs);            
        }
        catch (Exception e)
        {
            Console.WriteLine("不可读");
            Console.WriteLine(e.Message);
        }
    }

运行结果

This is some textThis is some more text,
and this is on a new line

The following is a subset of characters:

  
123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{
False
智能建造小硕

3.2 StreamWriter

实现一个 TextWriter,使其以一种特定的编码向流中写入字符。

3.2.1 常用属性和方法

构造方法和方法 描述
StreamWriter(Stream, Encoding, Boolean, Int32, Boolean) 使用指定的编码和缓冲区大小,为指定的流初始化 StreamWriter 类的新实例,并可以选择保持流处于打开状态。Boolean:如果要在文件开头查找字节顺序标记,则为true ;否则为 false。Int32:最小缓冲区大小。Boolean:如果在释放 StreamReader对象后保持流处于打开状态,则为 true;否则为 false。
StreamWriter(String, Encoding, FileStreamOptions) 使用指定的编码并配置指定的 对象,为指定文件初始化 StreamWriter 类的新 FileStreamOptions实例。String:要写入的完整文件路径。
BaseStream 返回基础流。
Encoding 获取在其中写入输出的 Encoding
Close() 关闭 StreamWriter对象和基础流,并释放与读取器关联的所有系统资源。
Write(Char[], Int32, Int32) 将字符的子数组写入流。第一个Int32;开始写入的 buffer 的索引。第二个Int32:最多读取的字符数。
ReadLine() 从当前流中读取一行字符并将数据作为字符串返回。
Dispose() 释放由 TextWriter对象使用的所有资源。
Write(String) 将字符串写入流
WriteLine() 将行终止符写入文本流。

3.1.2 代码示例

 static void Main(string[] args)
    {
        //获取C盘下的子文件目录
        DirectoryInfo cDirs = new DirectoryInfo(@"G:\Desktop\archive1");
        //* (星号):在该位置的零个或多个字符。?(问号):在该位置的零个或一个字符。
        FileInfo[] directoryInfos = cDirs.GetFiles("*",SearchOption.AllDirectories);
        // 将目录名写入文件
        using (StreamWriter sw = new StreamWriter("G:\\Desktop\\archive1\\Test3.txt"))
        {
            foreach (FileInfo dir in directoryInfos)
            {
                sw.WriteLine(dir.FullName);
            }
        }
        // 读取文件的每一行
        string line = "";
        using (StreamReader sr = new StreamReader("G:\\Desktop\\archive1\\Test3.txt"))
        {
            while ((line = sr.ReadLine()) != null)
            {
                Console.WriteLine(line);
            }
        }
    }

运行结果

G:\Desktop\archive1\AppSettings.dat
G:\Desktop\archive1\Test3.txt
G:\Desktop\archive1\新建文件夹\MyTest.txt
G:\Desktop\archive1\新建文件夹\MyTest1.txt

其它两对StringReader 与 StringWriter TextReader与 TextWriter 可阅读参考文献:

StringReader 类 (System.IO)​docs.microsoft.com/zh-cn/dotnet/api/system.io.stringreader?view=net-6.0

更多I/O流通用案例:

通用 I/O 任务​docs.microsoft.com/zh-cn/dotnet/standard/io/common-i-o-tasks

C#系列教程系列将持续更新,和大家一起学习、共同进步!

动图封面  

往期推荐

智能建造小硕:C#中常用I/O流介绍、 FileStream类及FileMode、FileAccess、FileShare1 赞同 · 0 评论文章 智能建造小硕:详细总结C#中的文件和I/O流之文件和目录(File 、 FileInfo、Directory、DirectoryInfo和Path)1 赞同 · 0 评论文章 智能建造小硕:一文读懂C#中的正则表达式知识(字符转义/字符类/ 定位点/ 分组构造 /数量词/反向引用构造/替换构造/替代/正则表达式选项)(理论篇)1 赞同 · 0 评论文章

欢迎关注公众号【智能建造小硕】(分享计算机编程、人工智能、智能建造、日常学习和科研经验等,欢迎大家关注交流。)

标签:StreamWriter,字节,字符,C#,写入,WriteLine,StreamReader,读取器,读取
From: https://www.cnblogs.com/sexintercourse/p/16647555.html

相关文章

  • 关于配置中科大的校园网络ustc-guest ustcnet eduroam的连接
    又是一年开学季,想到自己开学的时候经常搞不懂校园网的配置和连接(实际上过了一年多才搞清楚),于是写下这篇文档看看能不能帮到更多ustcers。目前的校园网大概有三类,一个是免......
  • C++ 打印杨辉三角/贾宪三角/帕斯卡三角
    #include<iostream>#include<iomanip>#include<windows.h>#include<fstream>#include<string>usingnamespacestd;#defineN10intmain(){inta[N][N......
  • 穿越时间·Plus! 2001年 Microsoft Plus! for Windows XP
    穿越时间·Plus!2001年MicrosoftPlus!forWindowsXP穿越时间更多内容请移步关注百度百家号:穿越时间我的电脑​关注 35人赞同了该文章......
  • 盘点 10个 C# 开源项目 yyds!
    盘点10个C#开源项目yyds!搜罗Github挖掘优质开源项目,分享高效率工具!​关注 6人赞同了该文章只推荐干货!当然这些开源项目都是个人或组织......
  • 最近的一些 CF 题(9.1起)
    1.CF623BB.ArrayGCD先考虑没有操作2的情况,由于不允许全删,所以至少会留下\(a_1\)与\(a_n\)中的一个,那么它们的质因数中必有一个需要成为公因数,由于最大公因数......
  • ubuntu 16.04 vs code中调试ORB-SLAM3
    如果是在vscode中编译,在vscode中调试,那么执行如下,如果还是在终端中编译,只在vscode中调试,那么应该可以忽略(1-3)注意修改build.sh文件中最下面的DCMAKE_BUILD_TYPE为Deb......
  • ExpressBurn Plus for Mac(mac光盘刻录软件)中文版
    有没有适用于macOS操作系统的光盘刻录软件?这里带来ExpressBurnPlusforMac。ExpressBurnMac中文版让用户可以快速完整的将音频,视频和数据刻录到Mac上的CD,DVD和蓝光光盘......
  • canvas实现图片压缩
    有时候页面上传的图片太大,难以进行图片识别,就需要在传给接口前先做压缩的处理,使用canvas进行图片压缩可以等比例压缩,不会出现失真模糊的情况。/***imgData原图base64*i......
  • 6.引入Nacos组件
    1.Docker安装Nacos拉取镜像、创建目录及配置文件dockerpullnacos/nacos-server:latest#拉取镜像mkdir-p/data/nacos/logs/data/nacos/init.d#创......
  • C++正则匹配字符串
    以下实例使用C++正则从一串混乱的字符串中匹配带小数点的数字点击查看代码#include<iostream>#include<regex>usingnamespacestd;intmain(){smatchres......