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());
Related
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();
}
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;
}
When I download a ZIP file from Amazon S3 and extract it using Java, it does not preserve the original timestamp of the file inside the ZIP.
Why? Here's the uncompress Java code:
public void unzipFile(String zipFile, String newFile) {
try {
FileInputStream fis = new FileInputStream(zipFile);
BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis);
FileOutputStream fos = new FileOutputStream(newFile);
final byte[] buffer = new byte[1024];
int len = 0;
while ((len = zis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
//close resources
fos.close();
zis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Basically, I want the timestamp of the file inside of the zip file, say file X has JAN-01-2010 to be preserved. But file X's is overwridden with the timestamp of the ZIP file, which has SEP-20-2013.
It's because you are putting the contents of the Zip File into a new File.
You could try something like:
public void unzipFile(String zipFile, String outputFolder){
try {
byte[] buffer = new byte[1024];
File folder = new File(outputFolder);
if(!folder.exists()){
folder.mkdir();
}
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
ZipEntry ze = zis.getNextEntry();
while(ze!=null){
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
//create all non exists folders
//else you will hit FileNotFoundException for compressed folder
new File(newFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
newFile.setLastModified(ze.getTime());
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Pulled from: http://www.mkyong.com/java/how-to-decompress-files-from-a-zip-file/ With Modifications to add Modified Time.
What I am trying to do is to zip a generated csv file. The file does get generated without issue until it comes to this code here. So the code throws the exception at zos.close() here's the code
try {
FileOutputStream fos = new FileOutputStream(file.getPath());
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream in = new FileInputStream(file.getPath());
String fullCSVFileName = file.getName();
String fullFileName = fullCSVFileName.substring(0, fullCSVFileName.length()-3);
String fullZipFileName = fullFileName + "zip";
ZipEntry ze= new ZipEntry(fullZipFileName);
if(ze != null) zos.putNextEntry(ze);
fos = new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName);
zos = new ZipOutputStream(fos);
byte[] buffer = new byte[1024];
int len;// = in.read(buffer);
while ((len = in.read(buffer)) > 0) {
Logger.debug("in Loop, len = " + len);
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
Logger.debug("Zipping complete!");
} catch(IOException ex) {
Logger.error(ex);
}
Corrected Code
try{
String fullCSVFileName = file.getName();
String fullFileName = fullCSVFileName.substring(0, fullCSVFileName.length()-3);
String fullZipFileName = fullFileName + "zip";
FileOutputStream fos = new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream in = new FileInputStream(file.getPath());
ZipEntry ze= new ZipEntry(fullZipFileName);
if(ze != null){
zos.putNextEntry(ze);
}
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
Logger.debug("Zipping complete!");
}catch(IOException ex){
Logger.error(ex);
}
You create fos and zos once at the top of your code:
FileOutputStream fos = new FileOutputStream(file.getPath());
ZipOutputStream zos = new ZipOutputStream(fos);
then add a ZipEntry:
if(ze != null) zos.putNextEntry(ze);
then redifine them later:
fos = new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName);
zos = new ZipOutputStream(fos);
then close the new zos. You never closed, nor wrote to the first zos (which had a ZipEntry) and never added a ZipEntry to the second (which you tried to close without any). Hence, the At Least One ZipEntry error.
------------ Edit --------------
Try adding zos.finish(), also, your close() methods should be in a finally block...
ZipOutputStream zos = null;
FileInputStream in = null;
try{
String fullCSVFileName = file.getName();
String fullFileName = fullCSVFileName.substring(0, fullCSVFileName.length()-3);
String fullZipFileName = fullFileName + "zip";
ZipOutputStream zos = new ZipOutputStream(
new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName));
in = new FileInputStream(file.getPath());
zos.putNextEntry( new ZipEntry(fullZipFileName) );
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.finish();
Logger.debug("Zipping complete!");
}catch(IOException ex){
Logger.error(ex);
}finally {
if ( zos != null ) {
try {
zos.close();
} catch ( Exception e ) {}
}
if ( in != null ) {
try {
in.close();
} catch ( Exception e ) {}
}
}
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];
}