【问题标题】:SerializationException was unhandled: The input stream is not a valid binary format. The starting contents (in bytes) areSerializationException 未处理:输入流不是有效的二进制格式。起始内容(以字节为单位)是
【发布时间】:2011-09-18 04:14:03
【问题描述】:

真的卡住了,任何帮助和/或 cmets 将不胜感激!

我编写了一个数据库程序,它需要能够将文件中的内容加载到列表中。所以基本上我正在尝试为此使用序列化和反序列化。发生错误的区域以粗体和斜体显示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApplication1
{
    class TheFile
    {
        //Version 1 serialiser, instance specific, so a bit of a pain

        public void SerializeObject(string filename, TheDocument document)
        {
            Stream stream = File.Open(filename, FileMode.Create);
            BinaryFormatter bFormatter = new BinaryFormatter();
            bFormatter.Serialize(stream, document);
            stream.Close();
        }
        public TheDocument DeSerializeObject(string filename)
        {
            TheDocument document;
            Stream stream = File.Open(filename, FileMode.Open);
            BinaryFormatter bFormatter = new BinaryFormatter();
            ***document = (TheDocument)bFormatter.Deserialize(stream);***
            stream.Close();
            return document;
        }
    }
}

我收到的错误如下:输入流不是有效的二进制格式。起始内容(以字节为单位)为:31-37-2F-30-39-2F-32-30-31-31-20-31-31-3A-30-36-3A ...

【问题讨论】:

  • btw - 错误是否显示在文件版本中?还是仅在与数据库交谈时?如果是后者……写/读 BLOB 的代码是什么?在与数据库通信时错误处理 BLOB 是很常见的......
  • 那是“17/09/2011 11:06:”。正在将当前日期和时间添加到文件中。先用记事本看看,然后用调试器检查 filename 参数。

标签: c# serialization deserialization


【解决方案1】:

我最近在其他地方看到过这样的报道,但我无法在其中找到解释。呈现的代码看起来应该没问题(虽然它会从一些using 语句中受益匪浅,但它们不会破坏成功案例,因为您正在调用.Close())。

但是!我还要警告说,IMO BinaryFormatter不是在数据库中存储的好选择,因为这表明将来需要读回它 BinaryFormatter 依赖于类型这一事实使得它在您对应用程序进行版本控制时非常脆弱。任何一种:创建新的应用程序版本、重命名/添加/删除字段、将属性更改为自动实现的属性、更改 .NET 版本、更改平台……可以使您的数据不可读,或者只能通过添加大量自定义活页夹代码才能读取。

强烈建议您考虑使用基于合约的序列化程序而不是 BinaryFormatter;任何一个:DataContractSerializer(但不是NetDataContractSerializer)、XmlSerializerJavascriptSerializer、JSON.Net。如果您想要二进制文件的大小和性能,那么协议缓冲区(具有多个 C# 实现,包括 protobuf-net)被设计为(由 Google 设计)具有版本容错性、小而快。由于该列表也是跨平台的,这也意味着如果您将平台切换到 Java、Mono、WinRT(新的 Windows 8 子系统)、PHP 或其他任何平台,您的数据是安全的。 BinaryFormatter不会对其中任何一个起作用。

【讨论】:

  • 嘿,非常感谢您的调查。很遗憾,我不能让它工作。
  • 另外,非常感谢您提供有关使用基于合同的序列化程序的建议!我一定会这样做!
  • 强调“可能”会使您的数据不可读。我刚刚测试了添加/删除字段和碰撞程序集版本,BinaryFormatter 并不关心(新字段为空,删除的字段不会导致异常,更改程序集版本也没有)。
【解决方案2】:

这成功了吗?

var path = "...";
var doc = new TheDocument(...);

SerializeObject(path, doc);
var restored = DeserializedObject(path);

Assert.IsNotNull(restored); // NUnit check; use appropriate code

评论太大了

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    相关资源
    最近更新 更多