Java InputStream读取问题
我有一个 Java 类,我在其中通过 InputStream 读取数据,
byte[] b = null;
try {
b = new byte[in.available()];
in.read(b);
} catch (IOException e) {
e.printStackTrace();
}
当我从 IDE (Eclipse) 运行我的应用程序时,它工作得很好。
但是,当我导出项目并将其打包在 JAR 中时,读取命令不会读取所有数据。我该如何解决它?
当 InputStream 是文件(~10kb)时,通常会出现此问题。
谢谢!
I have a Java class, where I'm reading data in via an InputStream
byte[] b = null;
try {
b = new byte[in.available()];
in.read(b);
} catch (IOException e) {
e.printStackTrace();
}
It works perfectly when I run my app from the IDE (Eclipse).
But when I export my project and it's packed in a JAR, the read command doesn't read all the data. How could I fix it?
This problem mostly occurs when the InputStream is a File (~10kb).
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通常我更喜欢在从输入流读取时使用固定大小的缓冲区。正如vilone指出的那样,使用available()作为缓冲区大小可能不是一个好主意,因为,比如说,如果您正在读取远程资源,那么您可能无法提前知道可用字节。您可以阅读 的 javadoc输入流以获得更多洞察。
这是我通常用于读取输入流的代码片段:
我在这里使用的 read() 版本将尽可能填充给定的缓冲区,并且
返回实际读取的字节数。这意味着您的缓冲区可能包含尾随垃圾数据,因此仅使用
bytesRead
以内的字节非常重要。请注意行
(bytesRead = in.read(buffer)) >= 0
,InputStream 规范中没有任何内容表明 read() 无法读取 0 个字节。根据您的情况,可能需要将 read() 读取 0 字节作为特殊情况进行处理。对于本地文件我从未经历过这种情况;然而,当读取远程资源时,我实际上看到 read() 不断读取 0 个字节,导致上述代码进入无限循环。我通过计算读取 0 字节的次数解决了无限循环问题,当计数器超过阈值时,我将抛出异常。您可能不会遇到这个问题,但请记住这一点:)出于性能原因,我可能不会为每次读取创建新的字节数组。
Usually I prefer using a fixed size buffer when reading from input stream. As evilone pointed out, using available() as buffer size might not be a good idea because, say, if you are reading a remote resource, then you might not know the available bytes in advance. You can read the javadoc of InputStream to get more insight.
Here is the code snippet I usually use for reading input stream:
The version of read() I'm using here will fill the given buffer as much as possible and
return number of bytes actually read. This means there is chance that your buffer may contain trailing garbage data, so it is very important to use bytes only up to
bytesRead
.Note the line
(bytesRead = in.read(buffer)) >= 0
,there is nothing in the InputStream spec saying that read() cannot read 0 bytes.You may need to handle the case when read() reads 0 bytes as special case depending on your case. For local file I never experienced such case; however, when reading remote resources, I actually seen read() reads 0 bytes constantly resulting the above code into an infinite loop. I solved the infinite loop problem by counting the number of times I read 0 bytes, when the counter exceed a threshold I will throw exception. You may not encounter this problem, but just keep this in mind :)I probably will stay away from creating new byte array for each read for performance reasons.
当InputStream耗尽时,
read()
将返回-1
。还有一个版本 read 接受一个数组,这允许您进行分块读取。它返回实际读取的字节数或位于 InputStream 末尾时的-1
。将此与动态缓冲区相结合,例如 ByteArrayOutputStream得到以下结果:这大大减少了必须调用的方法数量,并允许 ByteArrayOutputStream 更快地增长其内部缓冲区。
read()
will return-1
when the InputStream is depleted. There is also a version of read which takes an array, this allows you to do chunked reads. It returns the number of bytes actually read or-1
when at the end of the InputStream. Combine this with a dynamic buffer such as ByteArrayOutputStream to get the following:This cuts down a lot on the number of methods you have to invoke and allows the ByteArrayOutputStream to grow its internal buffer faster.
下面是下载文件(*.Png、*.Jpeg、*.Gif、...)并将其写入表示 HttpServletResponse 的 BufferedOutputStream 中的代码片段。
希望这有帮助。
Below is a snippet of code that downloads a file (*. Png, *. Jpeg, *. Gif, ...) and write it in BufferedOutputStream that represents the HttpServletResponse.
Hope this helps.