Reputation: 11
I'm currently developping on a webserver for my company , and i'am facing a corrupted zip file problem. At the end of a servlet. Here's the function header called at the very end of the servlet.
sendFile(directory, "s" + this.optimizerId + "-" + this.optimizerName + "-" + start.toDate(Defs.DB.DATE_PATTERN) + "-" + end.toDate(Defs.DB.DATE_PATTERN), FileExtension.NONE, ContentType.ZIP, response);
Here is the first send File function ...
public default void sendFile(File file, String fileName, FileExtension extension, ContentType type, HttpServletResponse response) {
if(type == ContentType.ZIP) {
String[] files = file.list();
if(files != null && files.length > 0) {
byte[] bytes = FileUtils.getZipBytes(file, files);
sendFile(new String(bytes), fileName, extension, type, response);
}
}
}
The "FileUtils.getZipBytes(file, files)" function is doing fine , it returns a byteArray. I even tried to create a zip file with ZipOutputStream a File , and on the server , the zip has litterally no problem. ( I will send the source code of this function if you think it's important , but i don't want to add useless complexity ).
Then , here's the code of the second sendFile function that is called from the first one.
public default void sendFile(String content, String fileName, FileExtension extension, ContentType type, HttpServletResponse response) {
response.setContentType(type.getExpression());
response.setHeader("Content-Disposition", "attachment; filename=\"" + FileUtils.encodeForFileName(fileName) + "." + extension.getExtension() + "\"");
OutputStream out = response.getOutputStream();
out.write(content.getBytes());
out.flush();
out.close();
}
Do you see any problem in these functions ?
The zip file is downloaded from the server. He is not empty (about 15.7KB). But when i try to open it , the file explorer of Fedora tell me that the file is corrupted.
I also tried to use the unzip command on the file , and i have the following error message.
Archive: s192-Système U carquefou-2023-01-26 000000-2023-01-26 235959(1).zip
caution: zipfile comment truncated
error [s192-Système U carquefou-2023-01-26 000000-2023-01-26 235959(1).zip]: missing 3249308257 bytes in zipfile
(attempting to process anyway)
error [s192-Système U carquefou-2023-01-26 000000-2023-01-26 235959(1).zip]: attempt to seek before beginning of zipfile
(please check that you have transferred or created the zipfile in the
appropriate BINARY mode and that you have compiled UnZip properly)
I thought it may be the FileUtils.getZipBytes(file, files) that returns a corrupted ByteArray. But i really don't think it is ... Here's the source code of this function
public static byte[] getZipBytes(File directory, String[] files) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
byte bytes[] = new byte[2048];
for (String fileName : files) {
FileInputStream fis = new FileInputStream(directory.getPath() +
System.getProperty("file.separator") + fileName);
BufferedInputStream bis = new BufferedInputStream(fis);
zos.putNextEntry(new ZipEntry(fileName));
int bytesRead;
while ((bytesRead = bis.read(bytes)) != -1) {
zos.write(bytes, 0, bytesRead);
}
zos.closeEntry();
bis.close();
fis.close();
}
zos.flush();
baos.flush();
zos.close();
baos.close();
return baos.toByteArray();
}
Upvotes: 1
Views: 361
Reputation: 21640
A zip file is not a string. You should drop the round trip from byte array to string and back to byte array.
Declare your sendFile()
method as
public default void sendFile(byte[] content, String fileName, FileExtension extension, ContentType type, HttpServletResponse response) {
response.setContentType(type.getExpression());
response.setHeader("Content-Disposition", "attachment; filename=\"" + FileUtils.encodeForFileName(fileName) + "." + extension.getExtension() + "\"");
OutputStream out = response.getOutputStream();
out.write(content);
out.flush();
out.close();
}
And call it as
sendFile(bytes, fileName, extension, type, response);
The problem with your approach is that new String(content).getBytes()
does not return a byte array with the same content as you started with.
Upvotes: 2