Java InputStream读取问题

| 我有一个Java类,在这里我通过InputStream读取数据
    byte[] b = null;
    try {
        b = new byte[in.available()];
        in.read(b);
    } catch (IOException e) {
        e.printStackTrace();
    }
当我从IDE(Eclipse)运行我的应用程序时,它可以完美运行。 但是,当我导出项目并将其打包到JAR中时,read命令不会读取所有数据。我该如何解决? 当InputStream是一个文件(〜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
  }
}
我在这里使用的read()版本将尽可能填充给定的缓冲区, 返回实际读取的字节数。这意味着您的缓冲区有可能包含尾随的垃圾数据,因此仅使用最大为2的字节非常重要。 注意第3行,InputStream规范中没有任何内容表明read()无法读取0个字节。当read()读取0个字节作为特殊情况时,您可能需要处理这种情况,具体取决于您的情况。对于本地文件,我从未遇到过这种情况。但是,当读取远程资源时,我实际上看到read()不断读取0个字节,从而导致上述代码陷入无限循环。我通过计数读取0字节的次数来解决无限循环问题,当计数器超过阈值时,我将引发异常。您可能不会遇到此问题,但请记住这一点:) 出于性能原因,我可能不会为每次读取创建新的字节数组。     
        当InputStream耗尽时,
read()
将返回
-1
。还有一个带有数组的read版本,它允许您进行分块读取。它返回实际读取的字节数,或者在InputStream的末尾返回“ 5”。将其与动态缓冲区(例如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()
这大大减少了您必须调用的方法数量,并允许ByteArrayOutputStream更快地增加其内部缓冲区。     
        
File file = new File(\"/path/to/file\");

try {
   InputStream is = new FileInputStream(file);
   byte[] bytes = IOUtils.toByteArray(is);

   System.out.println(\"Byte array size: \" + bytes.length);
} catch (IOException e) {
   e.printStackTrace();
}
    
        以下是下载文件(*。Png,*。Jpeg,*。Gif ...)的代码片段,并将其写在表示HttpServletResponse的BufferedOutputStream中。
BufferedInputStream inputStream = bo.getBufferedInputStream(imageFile);
try {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int bytesRead = 0;
    byte[] input = new byte[DefaultBufferSizeIndicator.getDefaultBufferSize()];
    while (-1 != (bytesRead = inputStream.read(input))) {
        buffer.write(input, 0, bytesRead);
    }
    input = buffer.toByteArray();

    response.reset();
    response.setBufferSize(DefaultBufferSizeIndicator.getDefaultBufferSize());
    response.setContentType(mimeType);
    // Here\'s the secret. Content-Length should equal the number of bytes read.
    response.setHeader(\"Content-Length\", String.valueOf(buffer.size()));
    response.setHeader(\"Content-Disposition\", \"inline; filename=\\\"\" + imageFile.getName() + \"\\\"\");

    BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream(), DefaultBufferSizeIndicator.getDefaultBufferSize());
    try {
        outputStream.write(input, 0, buffer.size());
    } finally {
        ImageBO.close(outputStream);
    }
} finally {
    ImageBO.close(inputStream);
}
希望这可以帮助。     

要回复问题请先登录注册