Java中的内存映射zip文件

7
以下是我试图解决的问题:
我有大约100个二进制文件(总共158KB,它们的大小大致相同,相差不超过50%)。我需要有选择地解析其中的一些文件(在最坏的情况下可能有50个,在其他情况下可能只有1到5个)。顺便说一下,这是在Android设备上进行的。
什么是在Java中最快的方法?
一种方法可以将所有内容合并为一个文件,然后使用文件查找到达每个单独的文件。那样文件打开只需要被调用一次,通常很慢。但是,为了知道每个文件在哪里,需要在文件开头有某种表格 - 可以使用脚本生成 - 但是文件也需要按连接顺序在表格中进行索引,以便文件查找不必做太多工作(如有错误,请纠正)。
更好的方法是使文件内存映射,然后表格就不必按连接顺序排列,因为内存映射文件将具有随机访问(如有错误,请纠正)。
如果使用zip压缩,则创建该表格将是不必要的,因为zip压缩已经创建了一个表格。此外,不需要将所有文件连接起来。我可以对目录进行zip压缩,然后通过zip文件中的条目访问每个单独的文件。问题解决了。
除非zip文件没有进行内存映射,否则读取速度会变慢,因为系统调用比直接内存访问慢(如有错误,请纠正)。因此,我得出结论,最好的解决方案是使用内存映射zip存档。
但是,ZipFile条目返回InputStream以读取条目的内容。而MappedByteBuffer需要RandomAccessFile,它需要一个文件名作为输入,而不是InputStream。
有没有办法将zip文件进行内存映射以进行快速读取?或者有没有其他解决读取选择性文件的问题的方法?
谢谢
编辑:我测试了打开、关闭和解析文件的速度,以下是我发现的统计数据:
文件数:25(解析时缺少一个文件)
总打开时间:72毫秒
总关闭时间:1毫秒
总解析时间:515毫秒
(这对解析有利,因为解析缺少一个文件)
%总时间打开需要:12%
%总时间关闭需要:0.17%
%总时间解析需要:88%

每个文件打开所需的平均时间:2.88毫秒
每个文件关闭所需的平均时间:0.04毫秒
每个文件解析所需的平均时间:21.46毫秒


感谢你提供关于MappedByteBuffer的信息! - Matthew
1
我认为您的瓶颈不会在于打开文件。在硬盘上,这需要时间 - 您必须寻找并等待物品旋转到位。对于固态存储器而言,这应该是无关紧要的。 - iluxa
你可能已经拒绝了这个选项,但你尝试过把数据以某种不需要单独解析的形式存储在数据库中吗?你描述的问题听起来非常像数据库为您提供的功能。 - Chris DuPuis
1个回答

1

目前我会使用一个简单的API,比如RandomAccessFile,如果你真的需要的话再回头解决这个问题。

编辑 - 我不知道MappedByteBuffer。那似乎是正确的方法。为什么不先用单独的文件,然后再考虑将它们合并呢?


我认为瓶颈在于文件的打开和关闭操作,而不是实际读取文件,尽管我还没有测试过,也许最好使用“MappedByteBuffer”逐个读取每个文件。 - bkase
是的,我认为是这样。至少你会知道打开/关闭所需的开销有多大。 - Matthew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接