从FileInputStream到BufferedInputStream的转换

时间:2016-04-02 09:55:12

标签: java fileinputstream bufferedinputstream

我们在实验室中进行了一些练习,其中一个是将文件传输方法从FileInputStream转换为BufferedInputStream。它是一个客户端向Web服务器发送GET请求,该服务器发送请求的文件。 我提出了一个简单的解决方案,我只想检查它是否正确。

原始代码:

try { 
      FileInputStream fis = new FileInputStream(req);
      // req, String containing file name
      byte[] data = new byte [fis.available()]; 
      fis.read(data); 
      out.write(data); // OutputStream out = socket.getOutputStream();
    } catch (FileNotFoundException e){ 
      new PrintStream(out).println("404 Not Found"); 
    }

我的尝试:

try { 
      BufferedInputStream bis = new BufferedInputStream (new FileInputStream(req));
      byte[] data = new byte[4];

      while(bis.read(data) > -1) {
        out.write(data);
        data = new byte[4];
      }
    } catch (FileNotFoundException e){ 
      new PrintStream(out).println("404 Not Found"); 
    }

该文件是一个名为index.html的网页,其中包含一个简单的html页面。 我每次都必须重新分配数组,因为在最后一次执行while循环时,如果文件的大小不是4的倍数,则数据数组将包含上一次执行的字符,这些字符在浏览器中显示。 我选择4作为数据大小进行调试。 输出正确。

这是一个很好的解决方案还是我可以做得更好?

2 个答案:

答案 0 :(得分:1)

每次都不需要重新创建字节数组 - 只需覆盖它。更重要的是,你的循环内部存在概念上的错误。每次迭代只是将数组写入流,假设它全部有效。如果你检查 BufferedInputStream #read 您将看到它的文档可能无法读取足够的数据来填充整个数组,并将返回它实际读取的字节数。您应该使用此数字来限制您正在编写的字节数:




  while((int len = bis.read(data))>  - 1){
 out.write(data,0,len);
}
  



答案 1 :(得分:0)

我建议您在完成后关闭文件。默认情况下,BufferedInputStream使用8 KB缓冲区,您将缩减为较小的缓冲区。一个更简单的解决方案是一次复制8 KB而不使用添加的缓冲区

try (InputStream in = new FileInputStream(req)) {
  byte[] data = new byte[8 << 10];
  for (int len; (len = bis.read(data)) > -1; ) 
      out.write(data, 0, len);
} catch (IOException e) { 
  out.write("404 Not Found\n".getBytes()); 
}