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写好,再处理中间的数据处理流程。

猜你喜欢

转载自blog.csdn.net/enternalstar/article/details/132354443