Tulains Córdova
Tulains Córdova

Reputation: 2639

Servlet read/output binary file nor same checksum as original file

I have a servlet (JSP) that reads a file from disk and sends it as http response.

The downloaded file has not the same sha1sum that the original and some files seems to be corrupted.

My code is this:

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());

Why does downloaded file have different sha1sum as original file and why some but not all downloaded files are corrupt?

Upvotes: 0

Views: 271

Answers (1)

You must put the number of read bytes in a variable, and just write as many bytes that you read.

Your implementation always writes the whole buffer of 4096 bytes, no matter of how many bytes that actually were read.

Something like this:

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

Upvotes: 2

Related Questions