.NET框架中充满了一些示例,其中方法调用将返回一个Stream,然后您可以根据需要进行读取和实现。但这如何在幕后工作?什么支持流?
假设我正在编写一个解析器,它接受一些输入并将一些数据解析为预定义的格式。例如,如果我创建了一个MemoryStream,然后使用StreamWriter将其内容写入它,然后让该方法返回流,我将遇到问题,因为编写器将在完成后关闭底层流并且调用者将无法执行按预期阅读。
这通常如何管理?在需要之前,流的内容是否存储在对象中(如byte[]
),然后在调用请求流的方法时,它会在那时创建它还是什么?
答案 0 :(得分:5)
流是字节序列的抽象,例如文件,输入/输出设备,进程间通信管道或TCP / IP套接字。 Stream类及其派生类提供了这些不同类型的输入和输出的通用视图,将程序员与操作系统和底层设备的特定细节隔离开来。 [MSDN说]
所以我想你使用序列化,使用流中使用不同格式的序列化需要定义你的需求
序列化是将对象转换为字节以进行持久性存储的过程。反序列化过程将字节转换为对象,而不会丢失任何数据。序列化用于在文件或数据库中存储值,通过网络发送对象并转换回原始对象格式。 .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
答案 1 :(得分:2)
流可以由许多不同的东西支持。这就是源自Stream抽象基类的流的整个想法。
流可以由操作系统级文件流,内存,HTTP连接或任何其他可以履行Stream
合同的内容支持。
在MemoryStream
的情况下,后备存储只是一块内存。
在StreamWriter
的情况下,在其上调用Dispose()将关闭基础流。只要您仍想使用流,请确保不要丢弃编写器。此外,如果您想在写入后重新访问MemoryStream
,请确保将位置设置为开头,例如:
memStream.Seek(0, SeekOrigin.Begin);
答案 2 :(得分:1)
StreamWriter有一个重载的构造函数,可用于指示写入不关闭流。
此外,Stream应该有一个.WriteBytes方法,允许您完全避免使用StreamWriter。