【问题标题】:DataContractSerializer with MemoryStream missing bytes带有 MemoryStream 的 DataContractSerializer 缺少字节
【发布时间】:2014-01-23 07:31:11
【问题描述】:

我正在尝试使用 WCF DataContractSerializer 将 DataContract 对象序列化为 memoryStream。

然后我使用 memoryStream.ToArray 来获取序列化的内容。

最后,我使用另一个 fileStream 将 memoryStream 持久化到一个文件中。

我最初的工具是这样的。我在持久文件的末尾缺少字节。

    public virtual string SerializeTransient(DataObject data, string targetPath)
    {
        string securityCode;

        using (var memoryStream = new MemoryStream())
        {
            using (var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings {Indent = true}))
            {
                _serializer.WriteObject(xmlWriter, data);

                using (var fileStream = new FileStream(targetPath, FileMode.Create))
                {
                    securityCode = CalculateSecurityCode(memoryStream.ToArray());
                    memoryStream.WriteTo(fileStream);
                }
            }
        }

        return securityCode;
    }

如果我将持久化逻辑移出内部 using{} 块(见下文),则输出是正确的。几乎感觉就像 WriteObject 函数没有完成它正在做的事情。有人可以向我解释那里发生了什么吗?谢谢。

    public virtual string SerializeTransient(DataObject data, string targetPath)
    {
        string securityCode;

        using (var memoryStream = new MemoryStream())
        {
            using (var xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings {Indent = true}))
            {
                _serializer.WriteObject(xmlWriter, data);
            }

            using (var fileStream = new FileStream(targetPath, FileMode.Create))
            {
                securityCode = CalculateSecurityCode(memoryStream.ToArray());
                memoryStream.WriteTo(fileStream);
            }
        }

        return securityCode;
    }

【问题讨论】:

    标签: c# wcf stream


    【解决方案1】:

    XmlWriter 有一个内部缓冲区。您应该关闭/处理 XmlWriter 或调用 XmlWriter.Flush() 以强制将所有内容写入底层流 (memoryStream)。

    如果在 writer.Flush() 之前调用 memoryStream.ToArray(),那么一些字节可能会保留在内部写入缓冲区中。

    【讨论】:

    • 我明白了。这就是为什么在 XMLWriter 上调用 Dispose() 会有所作为。谢谢回复。那么当您写入 XMLWriter 时,您实际上是在写入其内部缓冲区吗?然后在显式调用 Close() 或 Dispose() 或 Flush() 时将内部缓冲区闪出到底层流?
    • 是的,实际的写入链是 XmlWriter -> XmlWriter internal StreamWriter -> MemoryStream。内部 StreamWriter 有一个 char[1024] 缓冲区,因此内容作为 char[1024] 块写入内存流。如果您的内容长度为 1030 个字符,那么最后 6 个字符将保留在缓冲区中,直到您调用 Flush 或 Close/Dispose writer。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多