How to convert a MultipartFile to .zip and then to byte?
Something like:
MultipartFile file;
ZipInputStream zip = new ZipInputStream(file.getInputStream());
Base64.getEncoder().encode(zip)
Converting MultipartFile to .zip file and retrieving its bytes:
public ResponseEntity handleFile(#RequestParam MultipartFile file) throws IOException
{
InputStream inputStream = file.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
ZipEntry zipEntry = new ZipEntry(file.getOriginalFilename());
zipOutputStream.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while((length = inputStream.read(bytes)) >= 0) {
zipOutputStream.write(bytes, 0, length);
}
zipOutputStream.close();
// Do something with the byteArrayOutputStream
System.out.println(byteArrayOutputStream.toString());
return ResponseEntity.accepted().build();
}
Related
I have a Multipart file upload request. The file is a zip file- .zip format.
How do i unzip this file?
I need to populate a Hashmap with each entry's filepath and filecontent.
HashMap<filepath, filecontent>
The code I have so far:
FileInputStream fis = new FileInputStream(zipName);
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(fis));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
int size;
byte[] buffer = new byte[2048];
FileOutputStream fos =
new FileOutputStream(entry.getName());
BufferedOutputStream bos =
new BufferedOutputStream(fos, buffer.length);
while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
bos.write(buffer, 0, size);
}
bos.flush();
bos.close();
}
zis.close();
fis.close();
}
Instead of using FileOutputStream, use ByteArrayOutputStream to capture the output. Then, before executing the 'close' operation on the BAOS, use the 'toByteArray()' method on it to get the contents as a byte array (or, use 'toString()'). So, your code should look like this:
public static HashMap<String, byte[]> test(String zipName) throws Exception {
HashMap<String, byte[]> returnValue = new HashMap<>();
FileInputStream fis = new FileInputStream(zipName);
ZipInputStream zis = new ZipInputStream(
new BufferedInputStream(fis));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
int size;
byte[] buffer = new byte[2048];
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
BufferedOutputStream bos =
new BufferedOutputStream(baos, buffer.length);
while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
bos.write(buffer, 0, size);
}
bos.flush();
bos.close();
returnValue.put(entry.getName(),baos.toByteArray());
}
zis.close();
fis.close();
return returnValue;
}
I am trying to copy a zipped bytes array to another one using ZipOutputStream/ZipIntputStream, but it seems that the result array is not equal the original one, why is that wrong?
public static void main(String[] args) throws IOException {
File file = new File("folder.zip");
byte[] bFile = new byte[(int) file.length()];
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
byte[] aFile = copyZippedFileBytes(bFile);
System.out.println(Arrays.equals(aFile, bFile));
}
public static byte[] copyZippedFileBytes(byte[] arr) throws IOException {
ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(arr));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(baos);
ZipEntry entry;
while ((entry = zipStream.getNextEntry()) != null) {
zipOutputStream.putNextEntry(entry);
// assume files are small
byte[] indexFileByte = new byte[(int) entry.getSize()];
zipStream.read(indexFileByte);
zipOutputStream.write(indexFileByte);
zipOutputStream.closeEntry();
}
zipOutputStream.close();
zipStream.close();
return baos.toByteArray();
}
Solved by updated CRC of the modified entry as follow:-
CRC32 crc = new CRC32();
crc.reset();
BufferedInputStream bis = new BufferedInputStream
(new ByteArrayInputStream(data));
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = bis.read(buffer)) != -1) {
crc.update(buffer, 0, bytesRead);
}
entry.setMethod(ZipEntry.STORED);
entry.setCompressedSize(data.length);
entry.setSize(data.length);
entry.setCrc(crc.getValue());
i can zipping files, but with wrong content ... for example - content in a.txt:
!"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚„…†‡‰Š‹ŚŤŽŹ‘’“”•–—™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ`
This is code for zipping file:
void zipping() throws FileNotFoundException, IOException {
OutputStream os = new FileOutputStream("C:\\...\\newZip.zip");
ZipOutputStream zos = new ZipOutputStream(os);
File folder = new File("C:\\...\\A");
for (final File fileEntry : folder.listFiles()) {
//ZipEntry ze2 = new ZipEntry(fileEntry.getPath());
//zos.putNextEntry(ze2);
zos.putNextEntry(new ZipEntry(fileEntry.getName()));
for (int i = 0; i < 10000; i++) {
zos.write(i);
}
}
zos.close();
}
Where is bug? Thanks for help.
You are writing bytes into the zip file, starting from 1 to 10000. So depending on the encoding used, the output you have shown is correct.
Maybe you should read from the files you want to zip. Below is the code modified from yours.
void zipping(File file) throws FileNotFoundException, IOException {
OutputStream os = new FileOutputStream("C:\\...\\newZip.zip");
ZipOutputStream zos = new ZipOutputStream(os);
File folder = new File("C:\\...\\A");
for (final File fileEntry : folder.listFiles()) {
FileInputStream in = new FileInputStream(fileEntry);
zos.putNextEntry(new ZipEntry(fileEntry.getName()));
// buffer size
byte[] b = new byte[1024];
int count;
// Read from file and write to zip file
while ((count = in.read(b)) > 0) {
zos.write(b, 0, count);
}
}
zos.close();
}
Modify your code like this -
OutputStream os = new FileOutputStream("C:\\newZip.zip");
ZipOutputStream zos = new ZipOutputStream(os);
File folder = new File("C:\\zipit");
byte[] buffer = new byte[1024];
for (final File fileEntry : folder.listFiles()) {
zos.putNextEntry(new ZipEntry(fileEntry.getName()));
FileInputStream in = new FileInputStream(fileEntry.getAbsoluteFile());
int len=0;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
zos.close();
I want to download multiple files in single zip file using java servlet. I successfully downloaded the zip file containing multiple files (in my web page). but the problem is that files are also downloaded in my server(for ex in my jboss bin folder).
Code:
public void createZipFile(String fileNames,HttpServletResponse response,HttpServletRequest request) {
try {
ZipOutputStream outStream1 = null;
ServletOutputStream outStream=null;
FileInputStream inStream =null;
FileOutputStream fos=null;
InputStream inputStream =null;
int bytesRead = 0;
String zipFileName = "zipFileName.zip";
response.setHeader("Content-Disposition", "attachment;filename=\""+zipFileName+"\"");
response.setHeader("Pragma", "private");
response.addHeader("Cache-Control", "no-transform, max-age=0");
response.setHeader("Accept-Ranges", "bytes");
response.setContentType("application/zip");
//fileNames contains multiple file name.so i want to split and get each file
String[] fileName = fileNames.split(",");
byte[] buffer = new byte[1024];
outStream1 = new ZipOutputStream(new FileOutputStream(zipFileName));
for(int i = 0; i < fileName.length; i++) {
String filePath=audioFile.getAllFiles(fileName[i], Integer.parseInt(userId));
inputStream = new URL("************************server File location***************************").openStream();
String fileNaming = fileName[i];
String[] tempFile = fileNaming.split("\\.");
String tempFileExt=tempFile[1];
String temporaryFile=tempFile[0]+"."+tempFileExt;
fos = new FileOutputStream(temporaryFile);//here is the problem(temporary file created in my server -bin folder.but i dont want this to create)
int length = -1;
while ((length = inputStream.read(buffer)) > -1) {
fos.write(buffer, 0, length);
}
inStream = new FileInputStream(fileName[i]);
outStream1.putNextEntry(new ZipEntry(fileName[i]));
fos.close();
inputStream.close();
while ((bytesRead = inStream.read(buffer)) > 0) {
outStream1.write(buffer, 0, bytesRead);
}
}
inStream.close();
outStream1.closeEntry();
outStream1.close();
int bytesRead1 = 0;
byte[] buff = new byte[1024];
ByteArrayOutputStream bao = new ByteArrayOutputStream();
FileInputStream inStream1 =new FileInputStream(zipFileName);
while ((bytesRead1 = inStream1.read(buff)) != -1)
{
bao.write(buff, 0, bytesRead1);
}
byte[] videoBytes = bao.toByteArray();
response.setContentLength(videoBytes.length);
outStream = response.getOutputStream();
outStream.write(videoBytes);
outStream.flush();
outStream.close();
bao.close();
response.flushBuffer();
} catch (Exception ex) {
ex.printStackTrace();
}
}
For whatever reason, you're copying the files twice. Once, to the file system via inputStream and fos, and the second time to the ZipFile, via inStream and outStream1.
Seems like you can simply remove all of the code related to inputStream and fos, and you won't create the files on your filesystem.
I have byte[] of zip file. I have to unzip it without creating new file, and get byte[] of that unzip file.
Please help me to do that
You can use ZipInputStream and ZipOutputStream (in the package java.util.zip) to read and write from ZIP files.
If you have the data in a byte array, you can let these read from a ByteArrayInputStream or write to a ByteArrayOutputStream pointing to your input and output byte arrays.
public static List<ZipEntry> extractZipEntries(byte[] content) throws IOException {
List<ZipEntry> entries = new ArrayList<>();
ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(content));
ZipEntry entry = null;
while ((entry = zipStream.getNextEntry()) != null)
{
System.out.println( "entry: " + entry );
ZipOutputStream stream= new ZipOutputStream(new FileOutputStream(new File("F:\\ssd\\wer\\"+entry.getName())));
stream.putNextEntry(entry);
}
zipStream.close();
return entries;
}
In case you need to deflate your zipped data and you are too lazy to deal with the streams, you can use the following code:
public byte[] deflate(byte[] data) throws IOException, DataFormatException {
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
byte[] output = outputStream.toByteArray();
return output;
}
If you have only one file in the zip, you could use the following code. If there are multiple files, just modify the if into a while.
public static byte[] toUnzippedByteArray(byte[] zippedBytes) throws IOException {
var zipInputStream = new ZipInputStream(new ByteArrayInputStream(zippedBytes));
var buff = new byte[1024];
if (zipInputStream.getNextEntry() != null) {
var outputStream = new ByteArrayOutputStream();
int l;
while ((l = zipInputStream.read(buff)) > 0) {
outputStream.write(buff, 0, l);
}
return outputStream.toByteArray();
}
return new byte[0];
}