【问题标题】:C# DataTable Binary SerializationC# DataTable 二进制序列化
【发布时间】:2017-10-18 02:25:36
【问题描述】:

真正困扰我的快速菜鸟问题,我正在序列化一个 DataTable 数组,但是当反序列化它时,会抛出“输入流不是有效的二进制格式”的异常

序列化

    public static bool saveToFile(DataTable[] NW, string path)
    {
        try
        {
            using (var stream = new MemoryStream())
            {
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream,NW);
                stream.Close();
                File.WriteAllBytes(path,stream.ToArray());
            }
            return true;
        }
        catch(Exception ex)
        {
            MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
            return false;
        }
    }

反序列化

public static DataTable[] loadFromFile(string path)
    {
        try
        {
            byte[] buffer = File.ReadAllBytes(path);
            var stream = new MemoryStream(buffer);
            IFormatter formatter = new BinaryFormatter();
            return (DataTable[])formatter.Deserialize(stream);
        }
        catch(Exception ex)
        {
            MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
            return null;
        }
    }

我也尝试过不使用 MemoryStream,而是使用 File.Open(string path, FileMode.Create/Open) 返回的文件流

此外,在将其写入文件之前,这是字节数组的外观:

阅读时

:

看起来它并没有真正将所有内容都写入文件?

【问题讨论】:

  • 绝对有必要以二进制格式保存吗?如果没有,DataSet 具有在其中写入所有 DataTables 的功能;到一个 xml 文件中,同样你可以从保存的 xml 文件中读取。
  • 二进制不是强制性的,我试图用二进制来做,所以我可以将每个表上的 RemotingFormat 设置为二进制,这样可以节省一些空间,因为导入的数据很大
  • 我刚刚将您的方法投入到生成数据的单元测试中。您的代码似乎工作正常。您是否有与您的问题相关的示例数据?您是否检查了保存的物理文件的文件大小差异?
  • 问题是数据表是从几个csv文件生成的,在调试器中浏览表时一切都在那里,问题真的是在阅读时。
  • 您是否在文本编辑器中打开了保存的文件?通过在单元测试中运行您的代码,我看到它无论如何都在为数据表写出 xml,并且文件大小实际上大于普通的 DataSet.WriteXml。无论哪种方式,我都会首先交叉检查您的 loadFromFile 方法读取的字节数与文件系统所说的文件的实际字节数。如果文件大小相同,则读取没有问题,它正在读取文件中的所有字节。首先找出问题所在。

标签: c# serialization binary deserialization


【解决方案1】:
    public static class DataTableSerializer
{
    public static byte[] FastSerialize(this DataTable tbl, out string tableSchema)
    {
        var tableItems = new object[tbl.Rows.Count][];
        for (var rowIndex = 0; rowIndex < tbl.Rows.Count; rowIndex++)
            tableItems[rowIndex] = tbl.Rows[rowIndex].ItemArray;

        var serializationFormatter = new BinaryFormatter();

        using (var buffer = new MemoryStream())
        {
            serializationFormatter.Serialize(buffer, tableItems);

            var tableSchemaBuilder = new StringBuilder();
            tbl.WriteXmlSchema(new StringWriter(tableSchemaBuilder));
            tableSchema = tableSchemaBuilder.ToString();

            return buffer.ToArray();
        }
    }

    public static DataTable FastDeserialize(byte[] serializedData, string tableSchema)
    {
        var table = new DataTable();
        table.ReadXmlSchema(new StringReader(tableSchema));

        var serializationFormatter = new BinaryFormatter();
        object[][] itemArrayForRows;

        using (var buffer = new MemoryStream(serializedData))
        {
            itemArrayForRows = (object[][]) serializationFormatter.Deserialize(buffer);
        }

        table.MinimumCapacity = itemArrayForRows.Length;
        table.BeginLoadData();

        for (var index = 0; index < itemArrayForRows.Length; index++)
        {
            var t = itemArrayForRows[index];
            table.Rows.Add(t);
        }

        table.EndLoadData();

        return table;
    }
}

【讨论】:

    【解决方案2】:

    按照 Lu Henry 的评论,它实际上是通过将表移动到数据集然后编写它来工作。

        public static bool saveToFile(DataTable[] NW, string path)
        {
    
            try
            {
                var NWDS = new DataSet();
                foreach (DataTable dt in NW) {
                    NWDS.Tables.Add(dt.Copy());
                }
                NWDS.WriteXml(File.Create(path));
                return true;
            }
            catch(Exception ex)
            {
                MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
                return false;
            }
        }
    
    
        public static DataTable[] loadFromFile(string path)
        {
            try
            {
                var NWDS = new DataSet();
                NWDS.ReadXml(File.Open(path,FileMode.Open));
                var NW = new DataTable[15];
                NWDS.Tables.CopyTo(NW,0);
                return NW;
    
            }
            catch(Exception ex)
            {
                MessageBox.Show("ERROR" + Environment.NewLine + ex.Message);
                return null;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-07-27
      • 1970-01-01
      • 2010-12-17
      • 2015-09-17
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 2012-06-15
      相关资源
      最近更新 更多