【问题标题】:openRawResource: does compressed files in APK get uncompressed completely?openRawResource:APK中的压缩文件是否完全解压缩?
【发布时间】:2012-08-21 20:49:39
【问题描述】:

我在 res/raw 中有一个自定义文件格式,这意味着它将在 APK 中被压缩。

假设我的应用程序已安装在设备上。当我通过openRawResource()打开文件时,是否完全解压内存中的文件?

例如如果它是一个 3MB 的文件,它会在内存中解压缩它吗?如果我只需要来自某个偏移量的 10KB 数据(并且我通过 BufferedInputStream.skip() 到达它),那么在调用 openRawResource() 时它仍然会消耗 3MB 吗?

更新:除非我忽略了某些内容,否则它似乎不会解压缩整个文件。考虑以下测试。

我在 res/raw 中添加了一个 30MB 的随机数据文件。它的扩展名不是ogg,mp3,png或类似的,所以它会被压缩在APK中。在下面的代码中,我寻找大约 19MB 的位置,并读取 cca.文件中的 117KB。它工作,即使未压缩的长度是 30MB。 (据我所知,1MB 的限制仅适用于资产,不适用于原始资源。)

is = context.getResources().openRawResource(R.raw.test); // test is a 30MB test.txt
DataInputStream dis = new DataInputStream(new BufferedInputStream(is, 8192));


dis.skip(19555125);
byte[] testArr = new byte[117412];
dis.readFully(testArr);
for (int i = 0; i < testArr.length - 117000; i++) {
    Log.w("LOG_TAG", "" + testArr[i]);
}

【问题讨论】:

标签: android inputstream apk


【解决方案1】:

是的,所有“可压缩”文件都已压缩。 “不可压缩”文件 是某些图像文件、zip 文件等,它们已经在 压缩形式,不会从压缩中受益。

请记住,如果您的文件较大,压缩可能会成为问题 超过1M。该文件将很好地压缩,Android 工具包将 愉快的打包,但是在手机上会报错 尝试检索它,因为手机拒绝解压缩文件 大于 1M。解决方法是给文件一个 jpg之类的扩展名,所以它不会被压缩

【讨论】:

  • 谢谢,尽管我没有问谁被压缩,谁没有被压缩(读你的第一句话,看起来你是这么想的)。当我打开此类压缩文件的 InputStream 时,我询问 Android 是否将 整个 文件解压缩到内存中。我用我的测试代码更新了我的原始帖子。
  • json 文件会被压缩吗?从 IDE 运行应用程序时文件是否会被压缩(未签名,即调试模式)?
【解决方案2】:

与此同时,在 Android 邮件列表中,Dianne Hackborn 回答了这个问题。 引用戴安娜的话:

在我认为 Gingerbread 之前,它会在内存中完全解压缩 上面将使用的内存量有限制(我认为是 1MB) 打开会失败。在当前版本的平台上 解压缩在您阅读时进行流式传输,没有大小限制。

我的测试证实了这一点。我刚刚在 GingerbreadICS 设备上对其进行了测试,它运行良好。在接下来的几天里,我还将在 Froyo (Android 2.2) 设备上对其进行测试,并将更新这篇文章。

当然,Dianne 肯定是对的,我敢肯定,但她说她认为“Gingerbread”是第一个支持它的版本,所以我会在 Froyo 上测试它不会有什么坏处。

P.S.:感谢 CommonsWare 发现 Dianne 的答案。

【讨论】:

  • APK 文件是否会压缩它们,即使在调试模式下(未签名)? “Dianne Hackborn”这条评论的来源在哪里?