从InputStream读取时发生了IOException

12

在Android平台上从InputStream读取时,我遇到了一个奇怪的问题。我不确定这是否是Android特有的问题,还是我在一般情况下做错了什么。

唯一与Android有关的是此调用:

InputStream is = getResources().openRawResource(R.raw.myfile);

这将返回一个从安卓资产中的文件所对应的InputStream。无论如何,这就是我遇到的问题所在:

bytes[] buffer = new bytes[2];
is.read(buffer);

执行read()时会抛出一个IOException异常。奇怪的是,如果我进行两次连续的单字节读取(或任何数量的单字节读取),就不会出现异常。例如,以下代码可以正常工作:

byte buffer;
buffer = (byte)buffer.read();
buffer = (byte)buffer.read();
任何想法为什么两个连续的单字节读取可以工作,但一次读取两个字节会抛出异常? InputStream 看起来没问题...is.available()返回了100多万个字节(应该是这样)。
堆栈跟踪在InputStream.read()之前显示了这些行:
java.io.IOException
at android.content.res.AssetManager.readAsset(Native Method)
at android.content.res.AssetManager.access$800(AssetManager.java:36)
at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:542)

将缓冲区大小更改为一个字节仍会引发错误。看起来只有在读入字节数组时才会引发异常。

如果将文件截断为100,000字节(文件原始大小为1,917,408字节),则可以正常工作。这是因为文件超过某个大小出现问题吗?

感谢任何帮助!
谢谢!


一个1MB的文件可以工作,但是一个1.5MB的文件却不能。是否有一些资产大小限制? - DJayC
4个回答

14

(我的帖子在android-developers上没有显示,所以我会在这里尝试重新发布)

如果我没记错的话,这个问题是由于访问作为构建APK的一部分压缩的文件而引起的。

因此,为了解决这个问题,请给它一个不会被压缩的文件扩展名。我忘记了哪些扩展名被跳过的列表,但已知已经被压缩的文件类型(例如mp3、jpg)可能起作用。


1
你说得完全正确。将扩展名改为.MP3确实起作用了。这是一个愚蠢的错误,应该有一种方法告诉它如果压缩某个文件会导致这种问题,就不要压缩它。谢谢。 - DJayC
@CommonsWare:除了读取压缩文件之外,还有其他方法可以从资产中读取文件吗?我的意思是,文件在打包成APK时被压缩,但我们仍然可以读取资产文件吗? - VSB

3
将文件扩展名更改为.mp3以避免文件压缩确实可以起作用,但应用程序的APK要大得多(在我的情况下是2.3 MB而不是0.99 MB)。是否有其他方法可以避免这个问题?以下是我的答案:从资源文件夹加载大于1M的文件

2

通过您的提示,我使用GZIP实现了一个示例代码这里 - VSB

0

你说得对,提取文件有一定的大小限制。你可以将较大的文件分割成1MB的块,并有一种方法来确定哪些文件由哪些块组成,在应用程序运行时将它们拼接在一起。


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