C# 流Stream详解(2)——FileStream、BinaryReader、MemorySream、SreamReader等之间的关系

【文件流】

电脑上的文件有很多,文本文件、音频文件、视频文件、图片文件等,这些文件会被持久化存储在磁盘上,其本质都是一堆二进制数据。

FileStream用于读取二进制文件。电脑上的所有文件,不管是文本、音频、视频还是其他任意格式的文件,都可以用FileStream读取。不过读取到的都是二进制数据,需要知道如何反序列化才能得到对应的看得懂的信息。像图片的png格式、视频的mp4格式等,都是公开的反序列化方法。

通过文件流(FileStream)可以做到更细粒度地读取文件,一部分一部分,甚至一个字节一个字节地去读文件,而不是一个文件一个文件地读取。

流整体的来看是不断有东西从一个地方到另一个地方,强调这个过程,例如高铁站进站人流是从站外到站内,文件流是从磁盘到内存,具体来看是流内基本单位从一个地方到另一个地方,例如人流的基本单位是一个人,文件流的基本单位是一个字节。

如果人比较多,五个人一组,一组一组进站,这也是流,基本单位是5个人。如果文件很大,分成很多个文件,一个文件一个文件的读取,也是流,基本单位是一个文件。

TextReader/TextWriter用来高效处理文本文件的读写,基本单位是字符,但它们是抽象类,不能实例化。StreamReader/StreamWriter用于实现文本与二进制之间的转换。(Json文件、cpp文件、cs文件、prefab文件等都是文本文件)

BinaryReader/BinaryWriter用于二进制文件的读写,基本单位是字节。

其他流

FileStream是从磁盘到内存的读和从内存到磁盘的写

MemoryStream是在内存中读写,用于解决内存中各种流的交换

NetWorkStream网络流用来处理服务器与客户端通信的流

BufferedStream**:** BufferedStream从其他Stream读取或写入字节,以提高某些I / O操作的性能。

GZipStream:用于实现压缩解压的流

Cryptostream:用于加密解密的流

文件流的基本操作FileMode

  • Open:打开文件,前提是文件已经存在
  • Create:创建文件
  • OpenOrCreate:打开文件,如果文件不存在,则创建文件
  • Append:附加内容,即向文件中添加新的内容
  • Truncate:打开文件时将文件里面的内容清空,简化了删除文件再创建同名文件的步骤

文件读写权限FileAccess

  • Read:读取权限
  • Write:写入权限
  • ReadWrite:读写权限

【Stream类】

Stream是流的抽象类,任何流都需要继承这个类,有C#预定义的各种流的实现,这些实现让我们不用关心操作系统和基础设备交互等信息。

流的三个基本操作是读取、写入、查找,分别对应三个基础属性CanRead、CanWrite、CanSeek

常用属性

  • Length:流的长度,也即文件的大小,文件本身会记录关于大小的信息,只需要读取文件头就能获得,而不需要读取到整个文件才知道大小。需要注意的是,由于内存对齐等原因,文件大小不一定等于内存占用大小
  • Position:当前读写流的位置,将文件内容看成一个很长的字节数组,Position相当于Index。在文件开头,Position=0;在文件末尾,Position= Array.Length-1

常用方法

  • abstract long Seek(long offset, SeekOrigin origin):指定读写流的位置。Stream. Seek(-10,Origin.End); 表示在流末端往前数第10个位置;Stream. Seek(0,Origin.Begin); 表示在流的开头位置;Stream. Seek(1,Orig`in.Current); 表示在流的当前位置往后数第1个位置。
  • abstract int Read (byte[] buffer, int offset, int count);从流当前位置读取数据放入一个buffer中,读取数据的长度为count,放入buffer中的起始位置是offset,返回实际从流中读取的长度。一般来说,返回值和count相等,如果在流的末尾,可能直接读完了,返回值比count小。
  • abstract void Write (byte[] buffer, int offset, int count):从当前流的位置写入数据,数据从buffer中来,从buffer的offset位置开始写入,写入数据的长度为count。
  • Close()和Dispose():没什么好说的,就是在读取数据进行一系列的处理之后,可能忘记调用了。建议写代码按照一定的顺序来,读取文件之后立刻先把close和dispose写好,再处理中间的数据处理流程。
相关推荐
~plus~43 分钟前
Harmony核心:动态方法修补与.NET游戏Mod开发
开发语言·jvm·经验分享·后端·程序人生·c#
htj101 小时前
C# 使用正则表达式
正则表达式·c#
~plus~1 小时前
WPF八大法则:告别模态窗口卡顿
开发语言·经验分享·后端·程序人生·c#
就是有点傻1 小时前
使用WPF的Microsoft.Xaml.Behaviors.Wpf中通用 UI 元素事件
c#
qq_297908012 小时前
C#报价系统陈列展示成本核算系统项目管理系统纸品非纸品报价软件
sqlserver·c#·.net·开源软件
CoderIsArt11 小时前
C#中的CLR属性、依赖属性与附加属性
c#
IGP915 小时前
20250606-C#知识:委托和事件
开发语言·c#
Kookoos16 小时前
ABP VNext 与 Neo4j:构建基于图数据库的高效关系查询
数据库·c#·.net·neo4j·abp vnext
张鱼小丸子_微辣17 小时前
.Net Framework 4/C# LINQ*
c#
..活宝..19 小时前
【Emgu CV教程】11.2、Scharr边缘检测
图像处理·计算机视觉·c#·emgu cv·图像分析