news 2026/6/17 2:38:29

C#WinForm BinaryWriter、BinaryReader 二进制读写+BufferedStream 缓存流读写+File类+StreamReader与StreamWriter 读写流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#WinForm BinaryWriter、BinaryReader 二进制读写+BufferedStream 缓存流读写+File类+StreamReader与StreamWriter 读写流

一、知识点概述

BinaryWriter(二进制写入器)与 BinaryReader(二进制读取器)是C#封装好的高级流操作类,专门用于以二进制形式读写本地文件。该类不能独立工作,必须依托 FileStream 文件流对象才可使用。

相较于原生FileStream,二进制读写工具最大优势:无需手动进行字符串与字节数组的转换,能够直接写入/读取字符串、整数、布尔值、小数等多种数据类型,极大简化文件开发操作。二进制保存的文件用记事本打开会出现乱码,属于正常现象,只能通过对应读取工具解析数据。

常用场景:保存游戏数据、软件配置信息、账号密码、加密存储文件、存储多类型复合型数据。

二、整体功能介绍

1. 按钮1:借助FileStream+BinaryWriter,以二进制模式向1.txt文件写入指定字符串;

2. 按钮2:借助FileStream+BinaryReader,读取二进制文件中的字符串,并赋值给窗体标题展示。

三、完整可运行源代码

using System; using System.IO; using System.Windows.Forms; namespace _3_BinaryWriter_和_BinaryReader { public partial class Form1 : Form { public Form1() { InitializeComponent(); //BinaryWriter和 BinaryReader: 二进制流读写操作,需要提供文件流对象 } //二进制写入数据 private void button1_Click(object sender, EventArgs e) { //1 创建文件流 主要是给BinaryWriter提供一个参数 FileStream file = new FileStream(@"1.txt",FileMode.Create,FileAccess.Write); //2 创建二进制写入对象(写入工具) BinaryWriter bw = new BinaryWriter(file); //3 直接写入字符串数据 bw.Write("世界杯中国什么时候进"); //4 关闭资源 bw.Close(); file.Close(); //5 释放内存资源 bw.Dispose(); file.Dispose(); } //二进制读取数据 private void button2_Click(object sender, EventArgs e) { //1 创建只读文件流 FileStream file = new FileStream(@"1.txt",FileMode.Open,FileAccess.Read); //2 创建二进制读取工具 BinaryReader br = new BinaryReader(file); //3 读取字符串类型的数据 string ss = br.ReadString(); //4 将读取的数据展示在窗体标题 this.Text = ss; //5 关闭、释放资源 br.Close(); file.Close(); br.Dispose(); file.Dispose(); } } }

四、二进制写入操作(button1)分步拆解

步骤1:创建FileStream文件流对象

FileStream file = new FileStream(@"1.txt",FileMode.Create,FileAccess.Write);

参数解析:

第一个参数 @"1.txt":文件相对路径,文件生成在程序运行根目录;

第二个参数 FileMode.Create:文件创建模式,文件不存在则自动新建,文件已存在则直接覆盖原有内容;

第三个参数 FileAccess.Write:设置文件流权限为写入权限,仅支持写入数据,无法读取数据。

步骤2:创建二进制写入工具

BinaryWriter bw = new BinaryWriter(file);

BinaryWriter无法单独使用,构造函数需要传入FileStream对象,绑定对应的文件流,所有写入操作最终都会交给文件流保存到本地。

步骤3:写入数据

bw.Write("世界杯中国什么时候进");

Write()为重载方法,支持string、int、double、bool等所有基础数据类型;内部自动完成字符串转二进制字节操作,不需要手动编码转换,简化开发。

步骤4:关闭资源

bw.Close(); file.Close();

Close()作用:关闭数据流,解除程序对当前文件的占用;规范写法:先关闭读写工具,再关闭底层文件流。

步骤5:释放内存

bw.Dispose(); file.Dispose();

Dispose()作用:销毁对象、释放内存资源,避免内存泄漏,是流操作必不可少的收尾步骤。

五、二进制读取操作(button2)分步拆解

步骤1:创建只读文件流

FileStream file = new FileStream(@"1.txt",FileMode.Open,FileAccess.Read);

参数解析:

FileMode.Open:打开指定文件,若文件不存在直接抛出异常;

FileAccess.Read:权限设置为只读,仅能读取文件内容,禁止写入、修改文件。

步骤2:创建二进制读取工具

BinaryReader br = new BinaryReader(file);

依托已开启的文件流,创建专属读取器,用于解析文件内的二进制数据。

步骤3:读取数据并展示

string ss = br.ReadString(); this.Text = ss;

ReadString():专门读取二进制文件中的字符串数据;

核心规则:写入什么类型数据,读取必须对应调用相同类型的方法,顺序、类型不可错乱,否则程序报错。

步骤4:关闭并释放资源

br.Close(); file.Close(); br.Dispose(); file.Dispose();

读取完成后必须关闭并释放资源,防止文件长期被程序占用,无法删除和修改。

六、读写工具配套读取方法

1. 字符串:Write(string) —— ReadString()

2. 整型数据:Write(int) —— ReadInt32()

3. 布尔类型:Write(bool) —— ReadBoolean()

4. 小数类型:Write(double) —— ReadDouble()

七、执行流程

1. 写入流程:创建写入文件流→初始化BinaryWriter→直接写入数据→关闭工具与文件流→释放内存;

2. 读取流程:创建只读文件流→初始化BinaryReader→匹配类型读取数据→展示数据→关闭释放所有资源。

八、知识点总结

1. BinaryWriter、BinaryReader 依赖 FileStream,不能独立实例化使用;

2. 二进制读写最大优点:自动完成字节转换,无需手动编写编码转换代码;

3. 写入和读取的数据类型、存储顺序必须完全一致;

4. 二进制文件记事本打开乱码属于正常现象,只能用BinaryReader解析;

5. 写入操作匹配Create+Write权限,读取操作匹配Open+Read权限;

6. 所有流对象使用完毕,必须执行Close关闭、Dispose释放资源。

九、常见易错点

1. 权限错误:写入使用Read权限、读取使用Write权限,直接运行报错;

2. 模式错误:读取文件使用Create,覆盖原有数据造成数据丢失;

3. 类型不匹配:写入字符串,读取调用读取int的方法,程序直接崩溃;

4. 遗漏收尾:未关闭文件流,文件被进程锁定,无法删除与移动;

5. 误解乱码:误以为二进制文件乱码是代码BUG,二进制文件本身不支持明文查看。

———————BufferedStream 缓存流读写——————

一、知识点简介

BufferedStream 叫做缓存流/缓冲流,属于优化版文件读写类。底层自带内存缓冲区,专门用来优化文件读写性能。

普通FileStream每次读写都会直接操作电脑硬盘,硬盘读写速度慢、损耗大;BufferedStream会先将数据暂存到内存缓冲区中,程序优先读写内存缓存,减少直接访问硬盘的次数,从而提升读写速度、降低硬盘损耗。

BufferedStream不能单独使用,必须包裹FileStream文件流对象,本质是对FileStream的功能升级与性能优化。

二、功能概述

1、写入原理:程序数据→内存缓冲区→统一写入硬盘;

2、读取原理:硬盘数据一次性加载到缓冲区→程序从内存读取数据;

3、本次案例包含两部分:缓存流写入文件(注释代码)、缓存流循环读取文件并展示到窗体标题。

三、完整源代码

using System; using System.IO; using System.Text; using System.Windows.Forms; namespace _3BufferedStream { public partial class Form1 : Form { public Form1() { InitializeComponent(); //BufferedStream:缓存区文件读写操作,主要把本地数据读取到缓存区里面 //后续读取直接读取缓存区数据,减少磁盘IO操作,提高读写速度 #region 【缓存流写入(注释部分)】 ////1.创建缓存流对象,包裹创建文件的文件流 //BufferedStream buffer = new BufferedStream(File.Create(@"1.txt")); ////2.字符串转为字节数组 //byte[] bs = Encoding.Default.GetBytes("主要把本地数据读取到缓存区里面,"); ////3.向缓冲区写入数据 //buffer.Write(bs, 0, bs.Length); ////4.Flush:强制刷新缓冲区,将缓存数据写入硬盘 //buffer.Flush(); ////5.关闭缓存流 //buffer.Close(); #endregion #region 【缓存流读取(主代码)】 //1.创建只读文件流,并包裹为缓存流对象 BufferedStream b1 = new BufferedStream(File.OpenRead(@"1.txt")); //2.根据缓存流数据长度,创建对应字节数组 byte[] bs = new byte[b1.Length]; //3.定义空字符串,用来拼接读取到的全部内容 string ss = ""; //4.循环读取缓冲区数据 //Read返回值>0:代表还读取到数据;返回值<=0:读取完毕 while (b1.Read(bs, 0, bs.Length) > 0) { //字节数组转字符串,累加保存 ss += Encoding.Default.GetString(bs); //控制台打印读取内容,方便调试查看 Console.WriteLine(Encoding.Default.GetString(bs)); } //5.将读取完整内容赋值给窗体标题 this.Text = ss; //6.关闭缓存流,释放文件占用 b1.Close(); #endregion } } }

四、缓存流写入代码分步详解

1、创建缓存流对象

BufferedStream buffer = new BufferedStream(File.Create(@"1.txt"));

File.Create(@"1.txt"):创建文件流,文件不存在新建,存在则覆盖;

将文件流作为参数传入BufferedStream,完成缓存流绑定,实现缓存读写。

2、字符串转字节数组

byte[] bs = Encoding.Default.GetBytes("主要把本地数据读取到缓存区里面,");

计算机底层只能识别字节,所有写入缓存/文件的字符串,必须转为byte字节数组。

3、Write写入缓冲区

buffer.Write(bs, 0, bs.Length);

将字节数组数据写入内存缓冲区,此时数据暂时保存在内存,并未直接写入硬盘。

4、Flush刷新缓冲区(重点)

buffer.Flush();

作用:强制将内存缓冲区中所有暂存的数据,一次性写入本地硬盘;如果不调用Flush,数据只会停留在内存,不会保存到文件。

5、Close关闭流

关闭缓存流,解除程序对文件的占用,同时自动清空缓冲区资源。

五、缓存流读取代码分步详解

1、初始化只读缓存流

BufferedStream b1 = new BufferedStream(File.OpenRead(@"1.txt"));

File.OpenRead:打开文件并生成只读文件流,只能读取不能写入;

外层包裹BufferedStream,启用缓存读取模式,优化读取效率。

2、创建字节缓存数组

byte[] bs = new byte[b1.Length];

根据缓存流内部数据总长度,创建匹配大小的字节数组,用来接收读取的数据。

3、while循环读取数据

while (b1.Read(bs, 0, bs.Length)>0)

Read方法返回值含义:

返回值 > 0:成功读取到字节数据,继续循环读取;

返回值 = 0:文件数据全部读取完毕,结束循环。

4、字节数组还原字符串

ss += Encoding.Default.GetString(bs);

将每次循环读取到的字节数组,还原为字符串并累加,最终拼接成完整文件内容。

5、数据展示与关闭流

this.Text = ss:将读取完整的文件内容,赋值给窗体标题进行展示;

b1.Close():读取完成,关闭缓存流,释放文件与内存资源。

六、核心方法解析

1、Write(字节数组,起始下标,长度):向内存缓冲区写入字节数据;

2、Read(字节数组,起始下标,长度):从缓冲区读取数据存入数组,返回真实读取字节数;

3、Flush():强制刷新缓冲区,将内存数据落地保存到硬盘;

4、Close():关闭缓存流,释放所有资源。

七、BufferedStream优点

1、减少硬盘IO访问次数:批量读写,避免频繁操作硬盘;

2、读写效率更高:内存读写速度远远快于硬盘读写速度;

3、延长硬盘寿命:降低硬盘频繁读写造成的硬件损耗;

4、适配大文件:大文件读写优先推荐使用缓存流。

八、知识点总结

1、BufferedStream是FileStream的包装类,必须依赖文件流才能使用;

2、核心原理:利用内存缓冲区中转数据,减少磁盘访问次数;

3、写入数据必须调用Flush(),否则数据仅保存在内存,无法保存到文件;

4、采用while循环读取文件,适配任意大小文件,避免数据读取不全;

5、流对象使用完毕必须Close关闭,防止文件被程序锁定占用。

九、易错点

1、写入缓存流忘记调用Flush(),数据丢失,文件为空;

2、OpenRead只能读取,不能写入,强行写入直接报错;

3、读取文件时文件路径错误、文件不存在,程序抛出异常;

4、不使用循环读取大文件,容易出现数据读取残缺;

5、混淆缓冲区与文件:缓冲区在内存,断电数据直接清空。

————————File类——————————

一、知识点介绍

1、File类属于静态类,位于System.IO命名空间,所有方法全部为静态方法,不需要实例化对象,直接通过类名调用。

2、分工区别:

Directory:专门用来操作文件夹

File:专门用来操作文件,支持文件创建、删除、复制、移动、一键读写、追加内容。

3、优缺点:File类写法简单,一行代码即可完成读写,适合小型文本文件;底层一次性加载全部数据,不适合超大文件,大文件建议使用FileStream缓存流。

二、完整源代码

namespace _5File类 { public partial class Form1 : Form { public Form1() { InitializeComponent(); //所有代码下面分段逐一讲解 } } }

三、第一段:整体文本读写 WriteAllText / ReadAllText

//写入完整文本 File.WriteAllText(@"1.txt","dsdssdfsfdfddsdd是多少",Encoding.Default); //读取完整文本 MessageBox.Show(File.ReadAllText(@"1.txt",Encoding.Default));

1、WriteAllText(覆盖写入)

作用:快速向文件写入字符串内容;文件不存在自动创建,文件已存在直接覆盖原有全部内容。

参数1:文件相对路径;参数2:需要写入的文本内容;参数3:编码格式。

2、ReadAllText(整体读取)

作用:读取目标文件中所有内容,整体返回为一个字符串,适合读取单行、简单文本。

四、第二段:数组分行读写 WriteAllLines / ReadAllLines

//定义字符串数组 string[] contents = { "张三丰", "杨过" }; //将数组换行写入文件 File.WriteAllLines(@"2.txt",contents); //读取文件,按行转为数组 string[] ss = File.ReadAllLines(@"2.txt"); foreach(string s in ss) { MessageBox.Show(s); }

1、WriteAllLines

接收字符串数组,自动将数组里面的每一个元素,单独占一行写入文件,自动换行,适合多条数据存储。

2、ReadAllLines

读取文件所有内容,文件的每一行对应数组中的一个元素,返回字符串数组;一般搭配foreach循环遍历读取每一行数据。

五、第三段:字节形式读写 WriteAllBytes / ReadAllBytes

//字节形式写入 File.WriteAllBytes(@"3.txt", Encoding.Default.GetBytes("dsdfdf颠三倒四")); //字节形式读取 MessageBox.Show(Encoding.Default.GetString(File.ReadAllBytes(@"3.txt")));

原理:和FileStream原理一致,以字节数组方式读写数据。

特点:适用性最强,不仅能读写txt文本,还可以读写图片、音频、视频等所有类型文件。

写入:字符串转字节数组;读取:字节数组还原为字符串。

六、第四段:基础文件操作(增、删、复制、剪切、判断)

File.Create(@"4.txt"); //创建空白文件 File.Delete(@"4.txt"); //删除指定文件 File.Move(@"4.txt",@"../5.txt"); //剪切/移动文件 File.Copy(@"../5.txt", @"6.txt"); //复制文件 File.Exists(@"6.txt"); //判断文件是否存在

1、Create():创建一个空白文件,返回FileStream文件流对象;

2、Delete():永久删除文件,删除后无法从回收站恢复;

3、Move():剪切文件,既可以移动文件位置,也可以用于重命名文件;

4、Copy():复制一份一模一样的文件;

5、Exists():判断文件是否存在,返回布尔值true / false,防止路径报错。

七、第五段:AppendText 追加写入(重点)

//获取程序当前运行绝对路径 Directory.GetCurrentDirectory(); //打开文件并开启追加模式 StreamWriter sw = File.AppendText("6.txt"); //在文件末尾追加写入内容 sw.Write(Directory.GetCurrentDirectory()); //关闭写入流,释放资源 sw.Close();

1、WriteAllText 属于覆盖写入,会清空旧数据;AppendText为追加写入,不会覆盖原有内容,在文件末尾新增数据。

2、File.AppendText():打开指定文件,返回StreamWriter写入对象。

3、Directory.GetCurrentDirectory():获取当前程序Debug运行目录的绝对路径。

4、sw.Write():向文件末尾写入内容;使用完毕必须Close()关闭流,防止文件被占用。

八、知识点总结

1、File是静态类,无需new对象,直接类名调用方法;

2、WriteAllText:覆盖写入普通文本;ReadAllText:读取全部文本;

3、WriteAllLines:数组分行写入;ReadAllLines:按行读取返回数组;

4、WriteAllBytes:字节读写,支持所有格式文件;

5、Create/Delete/Copy/Move/Exists 完成文件基础增删复制移动;

6、AppendText实现追加写入,解决覆盖旧数据的问题,结尾必须关闭流。

StreamReader与StreamWriter 读写流

一、知识点概述

StreamWriter 和 StreamReader 专门用于纯文本文件的读写操作,位于System.IO命名空间。

1、StreamWriter:文本写入流,专门用来写入字符串,支持换行写入,底层自动封装FileStream,不需要手动转换字节数组;

2、StreamReader:文本读取流,专门用来读取文本文件,一般采用while循环按行读取;

3、特点:按行读写、内存占用小、适合大文本;优于File类,File一次性加载全部内容,容易内存溢出。

二、完整源代码

using System; using System.IO; using System.Windows.Forms; namespace _6StreamReader_StreamWriter { public partial class Form1 : Form { public Form1() { InitializeComponent(); #region 【StreamWriter 写入(注释代码)】 ////1.创建文本写入流对象 //StreamWriter sw = new StreamWriter(@"1.txt"); ////2.定义数组数据 //string[] names = { "张三", "李四" }; ////3.遍历数组,逐行写入文件 //foreach (string name in names) //{ // sw.WriteLine(name); //} ////4.关闭写入流 //sw.Close(); #endregion #region 【StreamReader 读取(运行代码)】 //1.创建文本读取流对象,打开指定文件 StreamReader sr = new StreamReader(@"1.txt"); //2.定义空字符串,用来接收每一行读取的数据 string str = string.Empty; //3.循环按行读取文件 while ((str = sr.ReadLine()) != null) { //弹窗显示每一行内容 MessageBox.Show(str); } //4.关闭读取流 sr.Close(); #endregion } } }

三、第一部分:StreamWriter 文本写入(分段拆解)

1、创建写入流对象

StreamWriter sw = new StreamWriter(@"1.txt");

传入文件路径,自动创建FileStream;文件不存在自动新建,文件存在默认覆盖原有内容

2、定义需要写入的数据

string[] names = { "张三", "李四" };

定义字符串数组,存储多条需要写入文件的文本数据。

3、foreach遍历 + WriteLine换行写入

foreach (string name in names) { sw.WriteLine(name); }

WriteLine():写入内容并自动换行;

区别:Write()只写入内容,不会自动换行。

4、关闭流资源

sw.Close();

释放文件占用,保存数据,防止文件被程序锁定。

四、第二部分:StreamReader 文本读取(分段拆解)

1、创建读取流

StreamReader sr = new StreamReader(@"1.txt");

根据路径打开文本文件,创建只读读取流,只能读取文本,不能读取图片、视频。

2、定义接收变量

string str = string.Empty;

定义空字符串,专门用来接收ReadLine读取到的每一行数据。

3、while循环读取(核心重点)

while ((str = sr.ReadLine()) != null)

ReadLine():每次只读一行数据;

读取规则:读取到内容返回当前行字符串;读取完毕没有数据返回null;

循环逻辑:先读取赋值给str,再判断是否等于null,不等于null就继续读取。

4、展示数据

MessageBox.Show(str);

将每一行读取到的数据弹窗展示。

5、关闭读取流

sr.Close();

读取完成必须关闭流,解除程序对文件的占用。

五、核心方法总结

StreamWriter(写入)

1、Write():写入内容,不换行;

2、WriteLine():写入内容,自动换行;

3、Close():关闭写入流,保存资源。

StreamReader(读取)

1、ReadLine():读取单行数据,读完返回null;

2、ReadToEnd():一次性读取全部文本;

3、Close():关闭读取流。

六、File类 VS Stream读写类

1、File类:一行代码读写,简单粗暴,一次性加载全部内容,适合小文件;

2、StreamWriter/StreamReader:按行读写,内存占用极小,专门适合大文本文件。

七、易错点

1、StreamWriter默认覆盖文件内容,想要追加内容需要重载构造函数;

2、ReadLine只能读取文本,不能读取二进制文件;

3、while循环判断不能写反,必须判断 != null;

4、读写结束不Close,文件会被进程占用,无法删除修改;

5、编码不一致会出现中文乱码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/17 2:35:10

文件存储 | OpenIM

1. 背景​ 在即时通信系统里&#xff0c;图片、语音、视频、文件、视频封面等内容都属于对象数据。它们和普通文本消息不同&#xff0c;通常体积更大、上传时间更长、受网络波动影响更明显。如果所有文件都经由业务 API 服务中转&#xff0c;服务端会同时承担业务处理和大流量…

作者头像 李华
网站建设 2026/6/17 2:27:58

【大咖嘉宾出席、高届数会议、5大高校期刊联合支持】第十届教育、管理与社会科学国际学术会议 (ISEMSS 2026)

第十届教育管理与社会科学国际学术会议&#xff08;ISEMSS 2026&#xff09;由澳门城市大学、四川工商学院和新加坡城市科学出版社《国际化教育科学与理论》期刊联合主办&#xff0c;澳门城市大学教育学院承办&#xff0c;成都信息工程大学外国语学院、西南财经大学天府学院、四…

作者头像 李华
网站建设 2026/6/17 2:25:59

UVa 506 System Dependencies

题目描述 题目要求模拟软件组件的安装和移除过程。每个组件可能有依赖关系&#xff08;必须预先安装其他组件&#xff09;。安装命令可以显式或隐式安装组件&#xff0c;移除命令只能移除不再被需要的组件。需要根据命令执行相应的操作并输出结果。 输入格式 输入包含若干命令&…

作者头像 李华
网站建设 2026/6/17 2:14:15

企业级AI工作流编排实战:5大核心架构设计与实施策略

企业级AI工作流编排实战&#xff1a;5大核心架构设计与实施策略 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程&#xff0c;自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/aw/Awesome-Dify-Wo…

作者头像 李华
网站建设 2026/6/17 2:11:23

有交易经验但不会代码,怎么把一个想法拆成信号?

有交易经验的人&#xff0c;往往不缺想法。真正难的是把想法拆到程序能执行。手工交易时&#xff0c;一句话就能概括的判断&#xff0c;到了量化里要变成数据、条件、信号、动作和例外情况。比如“突破以后追一下”&#xff0c;听起来很简单。但程序需要知道突破什么、追多少、…

作者头像 李华
网站建设 2026/6/17 2:09:53

从零搭建Java萌宠社交系统:WebSocket实时聊天+动态发布模块实现

在宠物社交类项目开发中&#xff0c;用户动态分享、好友实时聊天是最核心的两大基础功能。传统的HTTP请求属于短连接&#xff0c;无法实现消息实时推送&#xff0c;很难满足社交场景的交互需求。因此在萌宠社交系统开发中&#xff0c;我们通常会基于SpringBoot整合WebSocket&am…

作者头像 李华