1

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

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

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

更新:除非我忽略了某些东西,否则它似乎并没有解压缩整个文件。考虑以下测试。

我在 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]);
}
4

2 回答 2

0

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

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

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

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

PS:感谢 CommonsWare 发现 Dianne 的答案。

于 2012-08-21T22:51:52.073 回答
0

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

请记住,如果您的文件大于 1M,压缩可能会成为问题。该文件会很好地压缩,Android 工具包会很乐意将其打包,但在手机上,当您尝试检索它时会出错,因为手机拒绝解压缩大于 1M 的文件。解决方法是给文件一个 jpg 或类似的扩展名,这样它就不会被压缩

于 2012-08-21T22:25:12.230 回答