Mic*_*ael 8 java inputstream file
我有一个Java类,我通过InputStream读取数据
byte[] b = null;
try {
b = new byte[in.available()];
in.read(b);
} catch (IOException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
当我从IDE(Eclipse)运行我的应用程序时,它非常有效.
但是当我导出我的项目并将其打包在JAR中时,read命令不会读取所有数据.我该怎么办呢?
当InputStream是File(~10kb)时,通常会发生此问题.
谢谢!
通常我更喜欢在从输入流中读取时使用固定大小的缓冲区.正如evilone指出的那样,使用available()作为缓冲区大小可能不是一个好主意,因为,例如,如果您正在读取远程资源,那么您可能事先不知道可用字节.您可以阅读InputStream的javadoc 以获得更多洞察力.
这是我通常用于读取输入流的代码片段:
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) >= 0){
for (int i = 0; i < bytesRead; i++){
//Do whatever you need with the bytes here
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里使用的read()版本将尽可能地填充给定的缓冲区并返回实际读取的字节数.这意味着您的缓冲区可能包含尾随垃圾数据,因此仅使用最多的字节非常重要bytesRead.
注意这一行(bytesRead = in.read(buffer)) >= 0,InputStream规范中没有任何内容表明read()无法读取0个字节.当read()根据您的情况读取0字节作为特殊情况时,您可能需要处理这种情况.对于本地文件,我从未经历过这种情况; 但是,当读取远程资源时,我实际上看到read()不断读取0个字节,导致上面的代码进入无限循环.我通过计算读取0字节的次数解决了无限循环问题,当计数器超过阈值时,我将抛出异常.你可能不会遇到这个问题,但请记住这一点:)
出于性能原因,我可能会远离为每次读取创建新的字节数组.
read()-1InputStream耗尽时将返回。还有一个带有数组的read版本,它允许您进行分块读取。它返回实际读取的字节数或-1输入流的末尾。将其与动态缓冲区(例如ByteArrayOutputStream)结合使用以获取以下内容:
InputStream in = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int read;
byte[] input = new byte[4096];
while ( -1 != ( read = in.read( input ) ) ) {
buffer.write( input, 0, read );
}
input = buffer.toByteArray()
Run Code Online (Sandbox Code Playgroud)
这大大减少了您必须调用的方法数量,并允许ByteArrayOutputStream更快地增加其内部缓冲区。