我需要在Java中解析(并转换和编写)一个大型二进制文件(大于内存)。我还需要在一个线程中尽可能高效地这样做。最后,正在读取的格式是非常结构化的,所以最好有某种解析器库(这样代码就接近复杂的规范)。
如果这一点重要的话,解析所需的展望量应该很小。
所以我的问题是:
在nio方面,我怀疑nio不会有多大帮助,因为我很可能是磁盘有限的(而且由于它是一个线程,所以简单地阻塞不会有任何损失)。此外,我怀疑基于io的解析器更常见。
发布于 2012-06-29 06:20:26
让我解释一下Preon是否以及如何处理您提到的所有关切:
我需要在Java中解析(并转换和编写)一个大型二进制文件(大于内存)。
这正是Preon被创造出来的原因。您希望能够处理整个文件,而无需将其完全加载到内存中。不过,程序模型为您提供了一个指向数据结构的指针,该数据结构似乎完全位于内存中。然而,Preon将尽量懒洋洋地加载数据。
为了解释这意味着什么,假设在数据结构的某个地方,您有一组以二进制表示形式编码的事物,其大小为常数;假设每个元素都将以20个字节进行编码。然后Preon首先将不会在内存中加载该集合,如果您要获取该集合之外的数据,它将永远不会触及编码表示的那个区域。但是,如果要选择该集合的第300元素,它将(而不是解码到第300元素的所有元素),计算该元素的偏移量,然后立即跳到那里。
从外部看,就好像您引用了一个已完全填充的列表。从内部看,只有当您要求时,它才会取出列表中的一个元素。(然后马上忘掉它,除非你指示Preon以不同的方式做事。)
我还需要在一个线程中尽可能高效地这样做。
我不知道你说得有效率是什么意思。它可能意味着有效的内存消耗,或有效的磁盘IO,或者您的意思是它应该非常快。我认为可以公平地说,Preon的目标是在一个简单的编程模型、内存使用和其他一些关注点之间取得平衡。如果您真的需要按顺序遍历所有数据,那么也许有一些方法在计算资源方面更有效,但我认为这将以“易于编程”为代价。
最后,正在读取的格式是非常结构化的,所以最好有某种解析器库(这样代码就接近复杂的规范)。
我实现对Java字节代码的支持的方式是只读取字节代码规范,然后将其中提到的所有结构直接映射到带有注释的Java类。我觉得Preon很接近你要找的东西。
您还可能希望签出预发射器,因为它允许您生成数据的带注释的六边形(如Java类文件的十六进制示例),这是我在任何其他库中都没有看到的功能。(提示:请确保鼠标悬停在十六进制数字上。)
它生成的文档也是如此。它的目标一直是确保它能够创建可以发布到维基百科的文档,就像这样。它可能还不完美,但我并不对它目前能够做的事情感到不满。(例如:这是为Java类文件规范生成的文档.)
如果这一点重要的话,解析所需的展望量应该很小。
好的,这很好。事实上,这对Preon来说是至关重要的。Preon不支持放眼。不过,它确实支持回顾过去。(也就是说,有时部分编码机制是由以前读取的数据驱动的。) Preon允许您声明指向前面读取的数据的依赖项。)
二进制数据有什么好的解析器库吗?
( Preon!-)
解析器支持流转换有多好(我希望能够在解析过程中将被解析的数据流到某个输出-我不想在写东西之前在内存中构建一个完整的解析树)?
如前所述,Preon在开始处理之前不会在内存中构造整个数据结构。所以,从这个意义上说,你很好。然而,Preon中没有任何作为第一级公民支持转换的东西,而且它对编码的支持是有限的。
在nio方面,我怀疑nio不会有多大帮助,因为我很可能是磁盘有限的(而且由于它是一个线程,所以简单地阻塞不会有任何损失)。此外,我怀疑基于io的解析器更常见。
Preon使用NIO,但只支持内存映射文件。
发布于 2012-06-27 16:28:38
对于NIO和IO,您是对的,使用IO应该是正确的选择--减少复杂性,面向流等。
对于二进制解析库-签出普隆
发布于 2012-06-27 16:30:01
使用内存映射文件,您可以阅读它,而不必担心您的内存,它是快速的。
https://stackoverflow.com/questions/11230768
复制相似问题