我们在实验室中进行了一些练习,其中一个是将文件传输方法从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作为数据大小进行调试。 输出正确。
这是一个很好的解决方案还是我可以做得更好?
答案 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());
}