Servlet读取/输出二进制文件,与原始文件的校验和相同

时间:2015-03-06 12:48:35

标签: java file jsp servlets

我有一个servlet(JSP),它从磁盘读取文件并将其作为http响应发送。

下载的文件与原始文件和某些文件似乎已损坏的sha1sum不同。

我的代码是:

File file = new File((String)application.getAttribute("path")+"/"+item);
if (!file.exists()){
    RequestDispatcher dispatcher = application.getRequestDispatcher("/not_found.jsp?item="+item);
    dispatcher.forward(request, response);
    return;
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename=\""+item+"\"");
Locale.setDefault(new Locale("ES","ve"));
FileInputStream fileIn = new FileInputStream(file);
ServletOutputStream outs = response.getOutputStream();
 byte[] outputByte = new byte[4096];
//copy binary contect to output stream
System.out.println(new java.util.Date()+"\tStart download\t"+item+"\t"+request.getRemoteAddr()+"\t"+request.getRemoteHost());
while(fileIn.read(outputByte, 0, 4096) != -1)
{
    outs.write(outputByte, 0, 4096);
}
fileIn.close();
outs.flush();
outs.close();
System.out.println(new java.util.Date()+"\tEnd Download\t"+item+"\t"+request.getRemoteAddr()+"\t"+request.getRemoteHost());

为什么下载的文件与原始文件有不同的sha1sum,为什么有些但并非所有下载的文件都已损坏?

1 个答案:

答案 0 :(得分:2)

您必须将读取的字节数放在变量中,并且只写入您读取的字节数。

您的实现总是写入4096字节的整个缓冲区,无论实际读取的字节数是多少。

这样的事情:

int i = 0;
while( (i=fileIn.read(outbyteByte, 0, 4096)) != -1){
    outs.write(outputByte,0,i);
}