C # 使用流

溪流对我来说有点神秘。我不知道什么时候使用哪个流以及如何使用它们。谁能给我解释一下流是如何使用的?

如果我理解正确的话,有三种流类型:

  • stream
  • read stream
  • write stream

这是正确的吗? 例如,MemorystreamFileStream的区别是什么?

127465 次浏览

我会从读 MSDN 上的流开始: Http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

内存流和文件流是分别用于处理原始内存和文件的流。

Stream只有一种基本类型。但是在各种情况下,一些成员在调用时会抛出异常,因为在该上下文中该操作不可用。

例如,MemoryStream只是一种将字节移入或移出内存块的方法。因此,你可以在它上面调用读和写。

另一方面,FileStream允许您从文件读取或写入(或两者兼而有之)。您是否能够实际读取或写入取决于文件是如何打开的。如果只为读访问而打开文件,则无法写入该文件。

我不认为那些不同种类的溪流。Stream 类具有 CanRead 和 CanWrite 属性,这些属性可以告诉您是否可以读取和写入特定的流。

不同流类之间的主要区别(比如 MemoryStream 和 FileStream)在于后台存储——数据从哪里读取或写入到哪里。从名字就能看出来。MemoryStream 只在内存中存储数据,FileStream 由磁盘上的文件支持,NetworkStream 从网络中读取数据等等。

流有利于处理大量数据。当同时将所有数据加载到内存中不切实际时,可以将其作为流打开并处理其中的小块数据。

溪流是用于传输数据的对象。中的所有其他流类都来自一个泛型流类 System.IO.Stream。NET 是派生的。Stream类处理字节。

具体的流类用于处理字节以外的其他类型的数据,例如:

  • 如果外部源是文件,则使用 FileStream
  • MemoryStream用于在内存中存储数据
  • System.Net.Sockets.NetworkStream处理网络数据

读/写数据流,如 StreamReaderStreamWriter不是数据流-它们不是从 System.IO.Stream派生出来的,它们的设计目的是帮助写和读取来自和来自数据流的数据!

为了扩展一下这里的其他答案,并帮助解释您将看到的大量示例代码,大多数情况下您不会直接读写流。流是传输数据的低级手段。

您会注意到,用于读取和写入的函数都是面向字节的,例如 WriteByte ()。没有处理整数、字符串等的函数。这使得流非常通用,但是如果您只想传输文本,那么使用它就不那么简单了。

但是。NET 提供在本机类型和低级流接口之间进行转换的类,并为您将数据传输到流或从流传输。一些值得注意的类别包括:

StreamWriter // Badly named. Should be TextWriter.
StreamReader // Badly named. Should be TextReader.
BinaryWriter
BinaryReader

要使用这些类,首先获取流,然后创建上述类之一并将其与流关联。例如。

MemoryStream memoryStream = new MemoryStream();
StreamWriter myStreamWriter = new StreamWriter(memoryStream);

StreamReader 和 StreamWriter 在本机类型和它们的字符串表示形式之间进行转换,然后将字符串作为字节在流之间传输。那么

myStreamWriter.Write(123);

将“123”(三个字符’1’,’2’然后’3’)写入流。如果您处理的是文本文件(例如 html) ,那么 StreamReader 和 StreamWriter 就是您要使用的类。

然而呢

myBinaryWriter.Write(123);

将写入四个字节,表示32位整数值123(0x7B,0x00,0x00,0x00,0x00)。如果您正在处理二进制文件或网络协议,可以使用 BinaryReader 和 BinaryWriter。(如果您正在与网络或其他系统交换数据,则需要注意 Endianness,但这是另一篇文章。)

记录流只是 physical字节流上的一个抽象(或包装)。这个 physical流称为 base stream。所以总是有一个基本流,在这个基本流上创建了一个流包装器,因此这个包装器以基本流类型(如 FileStreamMemoryStream等)命名。

流包装器的优点是您可以获得一个统一的 api 来与任何底层类型的 usb, file等流交互。

为什么要将数据视为流 ——因为数据块是按需加载的,所以我们可以将数据视为块进行检查/处理,而不是将整个数据加载到内存中。这是大多数程序如何处理大文件,例如加密操作系统映像文件。