【问题标题】:Android 2.2: best way to read small blocks of binary data from big files?Android 2.2:从大文件中读取小块二进制数据的最佳方法?
【发布时间】:2011-12-15 09:28:05
【问题描述】:

我正在为 Android 2.2 开发。

默认情况下,放在资源和资产中的内容在 APK 中被压缩,除非它们的扩展名表明它们已经被压缩(mp3、png)。而且,在Android 2.3之前,assets只能放小于1MB的未压缩文件。

问题一:

如果我将一个 1.5MB 的二进制文件放到 res/raw 中,并且我的程序使用它的标准 Android ID (R.raw.....) 来引用它,那么系统会将 整个文件拉入记忆?由于 1.5MB 是以压缩方式存储的,我想它必须如此。这是不愉快的,因为程序可能只需要从给定的文件偏移量加载 1KB 的数据。这可能会对应用性能/速度产生严重影响。

我看到了两种解决方案:

  1. (hack) 使用 mp3 或 png 扩展名;但我不确定这是否允许内存高效访问(即 inputstream.skipbytes 等)
  2. 安装后,第一次启动应用程序时,应用程序会将文件复制到自己的可写工作文件夹(在SD卡中)。从那时起,它将始终从那里访问文件,而不是 R.raw... 方式。因此,顺序读取肯定会起作用,即内存使用量不会超过从指定文件偏移量读取的实际数据(除了 inputstream.seek 实现使用的临时读取缓冲区,这些缓冲区经过优化,即我想很小)。

问题 2:

从大文件中高效读取二进制数据的最佳方法是什么?我不想将我的大文件分成许多小文件,除非这是唯一的方法。

【问题讨论】:

    标签: android performance memory-management binaryfiles


    【解决方案1】:

    我会选择#2 解决方案,然后使用RandomAccessFile 来避免线性访问。

    【讨论】:

    • 顺便说一句,我可以将我的连续读取优化为连续读取(由于程序语义,不费吹灰之力)。 IE。打开 FileInputStream 后,我可以解决它总是以增加的偏移量读取,无需向后搜索。在这种情况下,FileInputStream(没有seek)是合适的,因为我可以通过skipBytes()解决所有seek。在这种情况下, RandomAccessFile 比 FileInputStream 有什么好处吗? (也许 .seek 比 skipBytes 更好,因为它使用底层操作系统函数而不是读取整个文件?)
    • 从实现来看(参见codesearch.google.com/codesearch#cZwlSNS7aEw/libcore/luni/src/…),skip() 似乎也是通过 seek 实现的。所以在你的情况下,坚持FileInputStream 可能是个好主意。
    【解决方案2】:

    我也将选择解决方案 #2,但不是使用随机访问文件,而是使用 java.nio.MappedByteBuffer - 这样您将获得具有字节缓冲区语义的快速随机访问。

    【讨论】:

    • 听起来不错,但由于我还需要从字节中键入读取(readInt() 等),而且我不需要写入,我认为 FileInputStream/RandomAccessFile 更合适。考虑到性能,我想如果 RandomAccessFile 比 FileInputStream 快,那么 RandomAccessFile 应该和 MappedByteBuffer 一样快(只是使用不同的机制)。
    • 不确定。从字节缓冲区获取原始数据只是一个包装器方法调用 - 非常快且没有流带来的开销(但它必须对齐并且您必须注意字节顺序)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多