从 InputStream 读取时出现 IOException
Posted
技术标签:
【中文标题】从 InputStream 读取时出现 IOException【英文标题】:IOException while reading from InputStream 【发布时间】:2010-11-19 09:17:18 【问题描述】:我在从 android 平台上的 InputStream 读取时遇到了一个奇怪的问题。我不确定这是 Android 特有的问题,还是我做错了什么。
唯一特定于 Android 的就是这个调用:
InputStream is = getResources().openRawResource(R.raw.myfile);
这将为来自 Android 资产的文件返回一个 InputStream。无论如何,这就是我遇到问题的地方:
bytes[] buffer = new bytes[2];
is.read(buffer);
当 read() 执行时,它会抛出 IOException。奇怪的是,如果我进行两次连续的单字节读取(或任意数量的单字节读取),也不例外。例如,这有效:
byte buffer;
buffer = (byte)buffer.read();
buffer = (byte)buffer.read();
知道为什么两个连续的单字节读取工作但一次调用一次读取两个都会引发异常吗? InputStream 看起来不错...is.available()
返回超过一百万字节(应该如此)。
堆栈跟踪在 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 文件无效。资产有大小限制吗?? 【参考方案1】:将文件扩展名更改为 .mp3 以避免文件压缩确实有效,但应用程序的 APK 更大(在我的情况下为 2.3 MB 而不是 0.99 MB)。
有没有其他方法可以避免这个问题?
这是我的回答: Load files bigger than 1M from assets folder
【讨论】:
【参考方案2】:您可以使用 GZIP 自己压缩文件,并使用 GZIPInputStream 类解压文件。
http://developer.android.com/reference/java/util/zip/GZIPInputStream.html
【讨论】:
按照你的提示使用 GZIP 我实现了一个示例代码here【参考方案3】:(我发给 android-developers 的帖子没有显示,所以我会尝试在此处重新发布)
IIRC,这个问题来自于尝试访问在构建 APK 时压缩的文件。
因此,要解决此问题,请为其指定一个不会被压缩的文件扩展名。我忘记了跳过哪些扩展名的列表,但已知已经压缩的文件类型(例如,mp3、jpg)可能有效。
【讨论】:
你说得对。将扩展名重命名为 .MP3 有效。这是一个愚蠢的错误,如果它会导致此类问题,应该有一种方法告诉它不要压缩某个文件。谢谢 @CommonsWare:还有其他方法可以从asset读取压缩文件吗?我的意思是文件在打包成APK的过程中被压缩了,但是我们可以读取资产文件吗?【参考方案4】:您是正确的,因为提取文件有一定的大小限制。您可能希望将较大的文件拆分为 1MB 的片段,并有一种方法可以让您知道哪些文件由哪些片段组成,并在您的应用运行时将它们重新拼接在一起。
【讨论】:
以上是关于从 InputStream 读取时出现 IOException的主要内容,如果未能解决你的问题,请参考以下文章
将大型 JSON (InputStream) 放入 String 时出现内存不足错误
对于大文件,在标记 inputStream 并重置它时出现“重置为无效标记”的异常。