加载/保存数据的替代方法-无需序列化



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

或者,创建一个具有序列化功能的数据容器,其中包含未序列化的文件。

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

使用JSON.NET 进行JSON序列化

吃掉了所有东西!包括匿名类型。

编辑

我知道你说过"你不想要序列化",但根据你的声明"[…]标记了serialization属性的对象",我相信你没有尝试使用JSON.NET进行JSON序列化!

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

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

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

解决了这些问题,就可以进行反序列化了。如果文件是使用内置序列化程序序列化的,只需使用它,但如果它是较旧的格式(CSV,固定长度),则必须逐行将文件解析为表示行的对象,这些对象收集在表示文件的主对象中。

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

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

好吧,老式的方法是使用流访问操作并读取您想要的数据。通过这种方式,您几乎可以读取/写入任何文件。序列化只是基于某种契约自动执行此过程。

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

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

例如,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是原始的。查看MSDN了解更多信息。

最新更新