![]() |
1
1
注册表访问非常复杂。你基本上是在读一个大的二叉树。类设计应该很大程度上依赖于存储的数据结构。只有这样,您才能选择合适的类设计。为了保持灵活性,您应该为原语建模,如reg_sz、reg_expand_sz、dword、subkey等。DonSyme在他的书《专家F》中有一个关于二进制组合器的二进制解析的很好的章节。基本的思想是,您的对象自己知道如何从二进制表示中反序列化。当你有这样的字节流时
从BinaryReader开始,逐字节读取二进制对象。因为您知道第一件事必须是头,所以可以将其传递给头对象
为了保持性能,您可以将分析数据的时间延迟到稍后实际访问此实例或该实例的特定属性时。 由于Windows中的注册表可能会变得很大,因此无法立即将其完全读取到内存中。你需要把它切成块。Windows应用的一个解决方案是将整个文件分配到分页池内存中,分页池内存可以跨越几GB,但只有实际访问的部分从磁盘交换到内存中。这使得Windows能够高效地处理非常大的注册表文件。你的读者也需要类似的东西。懒惰的解析是一个方面,在文件中跳跃而不需要读取其中的数据的能力是保持性能的关键。 有关页面池和注册表的更多信息,请访问: http://blogs.technet.com/b/markrussinovich/archive/2009/03/26/3211216.aspx 您的API设计将取决于您如何读取数据以保持效率(例如,使用 memory mapped file 从不同的映射区域读取)。有了.NET 4,一个内存映射文件实现已经到来,现在已经相当不错了,但是围绕OS API的包装器也存在。 你的, 阿洛伊斯克劳斯 为了支持从内存映射文件延迟加载,不需要将字节数组读取到对象中,稍后再对其进行分析,而是先执行一步,然后只存储内存映射文件中内存块的偏移量和长度。稍后,当实际访问对象时,您可以读取和反序列化数据。这样,您就可以遍历整个文件并构建一个对象树,其中只包含偏移量和对内存映射文件的引用。这样可以节省大量的内存。 |
![]() |
2
3
这取决于您需要如何处理这些数据。如果只需要线性地处理一次,那么只需要占用内存中一个大文件的性能,可能会更快。 但是,如果您需要对文件进行各种各样的操作,而不仅仅是一个线性解析,那么我将把数据解析到一个轻量级数据库(如sqlite)中,然后对其进行操作。这样可以保留文件的所有结构,并加快对该文件的所有后续操作。 |
![]() |
Eric Bourque · 将旧的C++DLL转换为C# 7 年前 |
![]() |
NiPapen · 将参数缩放到0到1之间以进行优化 7 年前 |
![]() |
BeSha · 模板类的输入输出类型不同时如何处理构造函数 7 年前 |
|
Ryohei · 如何在我的软件包中使用decorator 7 年前 |
![]() |
ABu · 展开std::reference\u包装的成本 7 年前 |
![]() |
asafg · mac os.pkg.app的节点JS包装器 7 年前 |