序列化到流然后从流中读取

Serializing to stream and then reading from stream

尝试从 MemoryStream(由 XmlWriter 写入)中读取时, 它抛出一个 ObjectDisposedException ("Cannot access a closed Stream.").

我偶然发现在 'using' 语句中间关闭 XmlWriter 允许编码为 return 而不会抛出。这里有些可疑。

    public static string SerializeToString(T obj)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));

        using (var stream = new MemoryStream())
        using (var writer = XmlWriter.Create(stream))
        {
            serializer.Serialize(writer, obj);

            writer.Flush();
            // Swapping the flush for close fixes the ObjectDisposedException 
            //writer.Close();
            stream.Position = 0;


            using (var reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        }
    }

Silverlight 和 .NET 4.5 都会出现这种情况。

阅读之后,我可以根据 Jon 的回答直接从内存流中读取字符串 here return Encoding.UTF8.GetString(stream.GetBuffer(), 0, stream.Length);

但首先我想了解导致示例代码中出现异常的原因。

关闭 writer 也将 Close() 底层流对象。

您不需要显式关闭编写器,因为 using 语句会在块结束时自动为您完成。

using (var stream = new MemoryStream())
using (var writer = XmlWriter.Create(stream))
{       
    ...
    //writer.Close(); <=== don't do this
    ...
} // <=== stream and writer get closed here

示例代码显示的问题是双重处置(StreamReader 和 XmlWriter 都处置其 BaseStream[MemoryStream])。

将 StreamReader 放入 usings 的顶部块解决了这个问题。

但最后我不需要 StreamReader 来获取文本并执行以下操作:

        public static string SerializeToString(T obj)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (var memoryStream = new MemoryStream())
            using (var writer = XmlWriter.Create(memoryStream))
            {
                serializer.Serialize(writer, obj);
                return Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
            }
        }