【问题标题】:Alternative ways to load / save data - without serialization?加载/保存数据的替代方法 - 没有序列化?
【发布时间】:2012-07-17 15:20:22
【问题描述】:

好的。我知道如何使用序列化等,但由于这只适用于标记有序列化属性的对象 - 例如,我如何在不使用序列化的情况下加载数据并在应用程序中使用它?说一个数据文件。

或者,创建一个带有序列化的数据容器来保存未序列化的文件。

我使用的方法是二进制序列化和 XML 序列化。任何其他可以加载未知数据并可能以某种方式在 C# 中使用它的方法?

【问题讨论】:

  • 是的,但是说我想将一些原始数据加载到应用程序中。尝试序列化随机文件使其查找创建数据文件的类。

标签: c# serialization data-storage data-containers


【解决方案1】:

使用JSON.NET的JSON序列化

一切!包括匿名类型。

编辑

我知道您说“您不想要序列化”,但根据您的陈述“[...] 已标记有序列化属性的对象”,我相信您没有尝试使用 JSON.NET 进行 JSON 序列化!

【讨论】:

  • ...所以有了这个,我可以存储一个 DataContainer 来保存几个没有序列化标记的项目(类)?
  • 正如我在回答中所说,它什么都吃。它不需要`[Serializable]。
  • 我在您所说的参考中找不到任何内容,我尝试了 JSonConverting.Deserialize (something),但无法加载文件。
【解决方案2】:

也许术语的定义是有序的;序列化是“将数据结构或对象状态转换为可以在同一或另一个计算机环境中存储和“复活”的格式的过程”。几乎任何将“易失性”内存转换为持久数据并返回的方法都是“序列化”,因此即使您推出自己的方案来执行此操作,您也是在“序列化”。

也就是说,听起来您根本不想使用 .NET 二进制序列化。这实际上是正确的想法。二进制序列化很简单,但非常依赖于代码和环境。将可序列化的类移动到不同的命名空间,或使用 Microsoft CLR 序列化文件然后尝试在 Mono 中反序列化它,可能会破坏二进制序列化。

首先,您必须能够根据文件确定应尝试创建的对象类型。您根本无法打开一些“随机”文件,并期望能够在不知道文件中数据的结构的情况下从中获得任何有意义的东西。最简单的方法是文件告诉您,通过指定创建它的对象的类型名称(您希望在您的代码库中可用)。大多数内置序列化程序都是这样做的。文件可以告知消费者其格式的其他方式包括文件、行和/或字段标题代码(在旧标准中很常见,因为它们可以节省文件大小)和扩展名/MIME 类型。

整理好之后,就可以进行反序列化了。如果文件是使用内置序列化程序序列化的,只需使用它,但如果它是较旧的格式(CSV,固定长度),那么您必须逐行解析文件,将其解析为代表行的对象,收集在一个代表文件的主要对象。

查看 ETL(提取-转换-加载)流程模式。这是一种模块化、可扩展的架构模式,用于获取文件并将其转换为程序可以使用的数据:

  • 提取 - 系统的这一部分指向文件系统,或其他传入的原始数据“管道”,它的工作是打开文件,将数据提取为可以进一步操作的非常基本的对象格式,并将这些对象放入内存中的“队列”中以进行转换步骤。目标是尽可能快速有效地从管道中获取数据,但此时您需要对正在处理的数据有一定的了解,以便有效地封装数据以进行进一步处理;实际上将数据转换为您真正想要的格式会在稍后发生。
  • 转换 - 系统的这一部分获取提取的数据,并执行将数据放入代码库中的水合对象的逻辑。在这里,根据提取步骤中有关提取数据的文件类型的信息,您可以实例化一个表示数据模型的域对象,将原始数据分割成将作为数据成员存储的块,执行任何类型转换(您从文件中获取的数据通常是字符串格式或原始位,必须进行编组或以其他方式转换为更好地表示数据概念的数据类型),并验证新对象的内部结构是一致并符合已知的业务规则。水合的有效对象被放置在输出队列中,以供加载步骤处理。
  • 加载 - 此步骤从转换步骤获取水合的有效业务对象,并将它们持久保存到系统使用的数据存储中(例如 SQL 数据库或程序的本机平面文件格式)。

【讨论】:

    【解决方案3】:

    嗯,老式的方法是使用流访问操作并读出您想要的数据。这样你就可以读/写几乎任何文件。 序列化只是根据一些合同自动执行此过程。

    根据您的评论,我猜您的要求是在没有合同的情况下阅读任何类型的文件。

    假设您有一个原始文件,其中第一个字节指定字符串的长度,下一组字节表示字符串;

    例如,5 | H | e | l | l | o

    var stream = File.Open(filename);
    var length = stream.ReadByte();
    byte[] b = new byte[length];
    
    stream.Read(b, 0, length);
    
    var string = Encoding.ASCII.GetString(b);
    

    二进制 I/O 是最原始的。 Check MSDN for more.

    【讨论】:

      猜你喜欢
      • 2017-11-21
      • 2012-07-14
      • 1970-01-01
      • 2015-06-20
      • 2019-10-20
      • 2014-10-18
      • 2019-12-04
      • 1970-01-01
      • 2020-07-11
      相关资源
      最近更新 更多