2

.NET 框架充满了示例,其中方法调用将返回一个 Stream,然后您可以根据需要读取和实现该 Stream。但这是如何在幕后工作的呢?什么支持流?

假设我正在编写一个解析器,它接受一些输入并将一些数据解析为预定义的格式。例如,如果我创建了一个 MemoryStream,然后使用 StreamWriter 将我的内容写入其中,然后让该方法返回流,我会遇到问题,因为编写器将在完成时关闭底层流,而调用者将无法按预期阅读。

这通常是如何管理的?流的内容是否存储在对象中直到需要(如 a byte[]),然后当调用请求 Stream 的方法时,它会在那时创建它还是什么?

4

3 回答 3

5

流是字节序列的抽象,例如文件、输入/输出设备、进程间通信管道或 TCP/IP 套接字。Stream 类及其派生类提供了这些不同类型的输入和输出的通用视图,将程序员与操作系统和底层设备的具体细节隔离开来。[MSDN 说]

所以我想你使用序列化,通过使用流在.NET中使用不同格式的序列化需要定义你的需求

序列化是将对象转换为字节以进行持久存储的过程。反序列化过程将字节转换为对象,而不会丢失任何数据。序列化用于将值存储在文件或数据库中,通过网络发送对象并转换回原始对象格式。.NET Framework 提供了一组框架类库 (FCL),用于简化序列化过程。它对于在两个不同的应用程序之间发送数据非常有用。

.NET Framework 支持二进制序列化和 XML 序列化格式。XML 序列化只序列化公共字段。但是,二进制序列化将序列化所有私有和公共字段。序列化可以作为基本或自定义执行。当类应用了 SerializableAttribute 属性时,就会发生基本序列化。基本序列化不支持版本控制。自定义序列化类必须标记为 SerializableAttribute 并实现 ISerializable 接口。用户可以为二进制和 XML 序列化格式实现自定义序列化。自定义应用程序需要重写 GetObjectData。示例应用程序对二进制和 XML 序列化都使用自定义序列化。.NET Framework 支持与开发工具相关的设计器序列化。

自定义序列化是控制序列化和反序列化过程的过程。自定义序列化可以通过在序列化期间和之后运行自定义方法或通过实现 ISerializable 接口来实现。自定义序列化用于对序列化对象进行版本控制。如果序列化的对象改变了对象状态(在以后的版本中添加了一个新文件),自定义序列化用于获取值而不丢失数据。由于缺少属性,序列化对象的版本控制可能会失败。

如果用户想在序列化期间和之后使用自定义方法,用户应该使用 OnDeserializedAttribute、OnDeserializingAttribute、OnSerializedAttribute 和 OnSerializingAttribute 属性应用自定义序列化支持,以便在序列化和反序列化期间自定义数据。OptionalFieldAttribute 属性用于忽略旧版本数据以进行反序列化。格式化程序在反序列化期间不会给出任何错误。它允许在序列化/反序列化之前和之后更新对象。

我认为下面的链接可以帮助你
http://www.codeproject.com/Articles/422474/Serialization-using-different-formats-in-NET

于 2013-03-07T19:45:01.460 回答
2

流可以由许多不同的事物支持。这就是从Stream抽象基类派生的流的全部想法。

该流可以由操作系统级别的文件流、内存、HTTP 连接或任何其他可以履行Stream合同的东西来支持。

在后备存储的情况下,MemoryStream只是一块内存。

在 的情况下StreamWriter,对其调用 Dispose() 将关闭底层流。只要您仍然想使用流,请确保您不处置 writer。此外,如果您想在写入后重新访问 a MemoryStream,请务必将位置设置为开头,例如:

memStream.Seek(0, SeekOrigin.Begin);
于 2013-03-07T19:09:46.377 回答
1

StreamWriter 有一个重载的构造函数,您可以使用它来指示写入不要关闭流。

此外,Stream 应该有一个 .WriteBytes 方法,可以让您完全避免使用 StreamWriter。

于 2013-03-07T19:10:29.250 回答