I have a nice java code that unzips a .zip file. But problem with this code is
i need to create target folders(Note:Only folders not file) before running this code.
Otherwise i will get path not found exception.
So This code wont work if zip file content is not known before. so i think this is useless code. Anyone have better logic? or Bellow code need to be edited?
package com.mireader;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
*
* #author jon
*/
public class Decompress {
private String _zipFile;
private String _location;
public Decompress(String zipFile, String location) {
_zipFile = zipFile;
_location = location;
_dirChecker("");
}
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
byte[] buffer = new byte[1024];
int length;
int i=0;
while ((ze = zin.getNextEntry()) != null) {
Log.v("t", ze.toString());
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
Log.i("my","Comes to if");
_dirChecker(ze.getName());
}
else {
Log.i("my","Comes to else");
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
while ((length = zin.read(buffer))>0) {
fout.write(buffer, 0, length);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
Log.i("My tag","Success");
}catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
Log.i("mytag", "Creating new folder");
f.mkdirs();
System.out.print("stp:"+f.getName());
}
}
}
You can avoid the following piece of code
if(ze.isDirectory()) {
Log.i("my","Comes to if");
_dirChecker(ze.getName());
}
and add code similar to the one below in the file creator else part. It worked for me by creating the entire parent folders.
File file = createFile((baseDirectory +"/" + zipFile.getName()));
file.getParentFile().mkdirs();
It doesn't look that wrong, what exactly is your problem?
You create the directories as they appear in the zip file; I usually do it inline, but it's the same. Your code would fail if your zip file not has the directory stubs inside (which could happen with zip creators in the wild), so my unzip code doublechecks the existance of the directory before extracting each file:
if (zEntry.isDirectory()) new File(destDir+zEntry.getName()).mkdirs();
else
{
String dstEntryDir=new File(destDir+zEntry.getName()).getParent()+File.separator;
if (!fileExists(dstEntryDir)) new File(dstEntryDir).mkdirs();
copyStreamToFile(zFile.getInputStream(zEntry),destDir+zEntry.getName());
}
Related
I am making a game that needs to be updated.
I have two JAR files: Update.Jar and Game.Jar
Basically, I want to be able to modify Game.Jar without completely overwriting it.
I want to:
Open the Jar file as a Zip file from within code
Replace/add some resources
Repackage the Jar file.
Is there an easy way or classes that can do this? If not, what would be the cleanest approach to doing this?
A Java JAR file is a normal ZIP file. You can therefore open and modify it with code dealing with ZIPs.
Here's a snippet which works (courtesy of David):
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class JarUpdater {
public static void main(String[] args) {
File[] contents = {new File("F:\\ResourceTest.txt"),
new File("F:\\ResourceTest2.bmp")};
File jarFile = new File("F:\\RepackMe.jar");
try {
updateZipFile(jarFile, contents);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void updateZipFile(File zipFile,
File[] files) throws IOException {
// get a temp file
File tempFile = File.createTempFile(zipFile.getName(), null);
// delete it, otherwise you cannot rename your existing zip to it.
tempFile.delete();
boolean renameOk=zipFile.renameTo(tempFile);
if (!renameOk)
{
throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
}
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String name = entry.getName();
boolean notInFiles = true;
for (File f : files) {
if (f.getName().equals(name)) {
notInFiles = false;
break;
}
}
if (notInFiles) {
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(name));
// Transfer bytes from the ZIP file to the output file
int len;
while ((len = zin.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
entry = zin.getNextEntry();
}
// Close the streams
zin.close();
// Compress the files
for (int i = 0; i < files.length; i++) {
InputStream in = new FileInputStream(files[i]);
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(files[i].getName()));
// Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// Complete the entry
out.closeEntry();
in.close();
}
// Complete the ZIP file
out.close();
tempFile.delete();
}
}
In Java 7, the best way is to use the built in Zip File System Provider:
http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
i.e.
import java.util.*;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.*;
public class ZipFSPUser {
public static void main(String [] args) throws Throwable {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
// locate file system by using the syntax
// defined in java.net.JarURLConnection
URI uri = URI.create("jar:file:/codeSamples/zipfs/zipfstest.zip");
try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
Path externalTxtFile = Paths.get("/codeSamples/zipfs/SomeTextFile.txt");
Path pathInZipfile = zipfs.getPath("/SomeTextFile.txt");
// copy a file into the zip file
Files.copy( externalTxtFile,pathInZipfile,
StandardCopyOption.REPLACE_EXISTING );
}
}
}
~
So i created a zip and created a new sub folder in the zip file by creating a zip entry that ends in "\". How would i write to the subfolder?
My problem is i have a putnextEntry call on my ZipOutputStream in a for loop so after the folder gets created i then jump into a for loop where the different zip files are written. But they are written at the same level as the subdir within the zip.
What i think is happening is because i use putNextEntry with the first actual zip(not dir) entry it is closing the subfolder and writing to the root of the zip. Any ideas?
Code below
private int endprocess() {
try {
zipFolder(ripPath, zipOutputPath, "rips");
//zipFolder(destPDFfiles, zipOutputPath, "pdfs");
this.returnCode = 0;
//log.debug ( "Accumulator count: " + acount);
log.debug("Equivest count: " + ecount);
//log.debug ( "Assoc count: " + scount);
processEndOfEnvelope();
} catch (Exception reportException) {
log.logError("Caught exception in creating.");
reportException.printStackTrace();
this.returnCode = 15;
}
return (this.returnCode);
}
public static void zipFolder(String srcFolder, String dest, String outputFolder){
try{
ZipOutputStream zos = null;
FileOutputStream fos = null;
fos = new FileOutputStream(dest + "\\newzip.zip");
zos = new ZipOutputStream(fos);
addFolderToZip(srcFolder, zos, outputFolder);
zos.flush();
zos.close();
}catch(IOException e){
log.logError("**********************");
log.logError("IO Exception occurred");
log.logError(e.getMessage());
e.printStackTrace();
}
}
private static void addFileToZip(String srcFile, ZipOutputStream zos, String outputFolder){
try {
File folder = new File(srcFile);
if (folder.isDirectory()) {
addFolderToZip(srcFile, zos, outputFolder);
} else {
byte[] buffer = new byte[1024];
int length;
FileInputStream fis = new FileInputStream(srcFile);
ZipEntry ze = new ZipEntry("C:\\AWDAAV\\zip\\newzip.zip\\" + outputFolder + "\\" + folder.getName());
zos.putNextEntry(ze);
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
}
}catch(Exception e){
log.logError("**********************");
log.logError("Exception occurred");
log.logError(e.getMessage());
e.printStackTrace();
}
}
private static void addFolderToZip(String srcFolder, ZipOutputStream zos, String outputFolder){
try{
File folder = new File(srcFolder);
zos.putNextEntry(new ZipEntry(outputFolder + "\\"));
for(String fileName : folder.list()){
addFileToZip(srcFolder + "\\" + fileName, zos, outputFolder);
}
}catch(Exception e){
log.logError("**********************");
log.logError("Exception occurred");
log.logError(e.getMessage());
e.printStackTrace();
}
}
I had a look at your code and i think the ZIP API works just as you think.
Only you had some logic errors with the path names.
You need to convert the path names from the local names to the relative locations in the zip file.
Maybe you got confused somewhere in that area.
Here is my suggestion:
File: org/example/Main.java
package org.example;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws IOException {
MyZip myZip = new MyZip();
Path sourcePath = Paths.get("C:/Users/David/Desktop/a");
Path targetPath = Paths.get("C:/Users/David/Desktop/zip/out.zip");
Path zipPath = Paths.get("tadaa");
myZip.zipFolder(sourcePath, targetPath.toFile(), zipPath);
}
}
Update: Explanation of variables in main method
The sourcePath is a directory which content you want to include in the zip archive.
The targetPath is the output path of the zip file. For example the new zip file will be created at exactly that location.
The zipPath is the subdirectory within the zip directory where your content from sourcePath will be placed. This variable may also be set to null. If it is null the sourcePath will be put in the root of the new zip archive.
File: org/example/MyZip.java
package org.example;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class MyZip {
public void zipFolder(Path base, File dest, Path zipFolder) throws IOException {
try (FileOutputStream fos = new FileOutputStream(dest);
ZipOutputStream zos = new ZipOutputStream(fos)) {
addFolderToZip(base.getParent(), base, zos, zipFolder);
}
}
private void addFolderToZip(Path base, Path currentFolder, ZipOutputStream zos, Path zipFolder) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentFolder)) {
for(Path path : stream) {
Path relativePath = base != null ? base.relativize(path) : path;
Path pathInZip = zipFolder != null ? zipFolder.resolve(relativePath) : relativePath;
if(path.toFile().isDirectory()) {
zos.putNextEntry(new ZipEntry(pathInZip.toString() + "/"));
// recurse to sub directories
addFolderToZip(base, path, zos, zipFolder);
} else {
addFileToZip(path, pathInZip, zos);
}
}
}
}
private void addFileToZip(Path sourcePath, Path pathInZip, ZipOutputStream zos) throws IOException {
byte[] buffer = new byte[1024];
int length;
try (FileInputStream fis = new FileInputStream(sourcePath.toFile())) {
ZipEntry ze = new ZipEntry(pathInZip.toString());
zos.putNextEntry(ze);
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
}
}
}
ZipEntry.setLevel(filepath[in your case, \folder]);
I'm writing a java program that will extract zip file and rename the file inside it to the zip file name. For example: the zip file name is zip.zip and the file inside it is content.txt. Here i want to extract the zip file and the content.txt has to be renamed to zip.txt. I'm trying the below program.
And here there would be only one file in the zip file
Zip.Java
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class zip {
private static final int BUFFER_SIZE = 4096;
public void unzip(String zipFilePath, String destDirectory) throws IOException {
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
// if the entry is a file, extracts it
extractFile(zipIn, filePath, zipFilePath);
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
private void extractFile(ZipInputStream zipIn, String filePath, String zipFilePath) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
File oldName = new File(filePath);
System.out.println(oldName);
String str = zipFilePath.substring(zipFilePath.lastIndexOf("\\") + 1, zipFilePath.lastIndexOf("."));
System.out.println(str);
File zipPath = new File(zipFilePath);
System.out.println(zipPath.getParent());
File newName = new File(zipPath.getParent() + "\\" + str);
System.out.println(newName);
if (oldName.renameTo(newName)) {
System.out.println("Renamed");
} else {
System.out.println("Not Renamed");
}
bos.close();
}
}
UnZip.Java
public class UnZip {
public static void main(String[] args) {
String zipFilePath = "C:\\Users\\u0138039\\Desktop\\Proview\\Zip\\New Companies Ordinance (Vol Two)_xml.zip";
String destDirectory = "C:\\Users\\u0138039\\Desktop\\Proview\\Zip";
zip unzipper = new zip();
try {
unzipper.unzip(zipFilePath, destDirectory);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Here i was able to extract the file but unable to rename it. please let me knw where am i going wrong and how to fix it.
Thanks
Close your BufferedOutputStream directly after the last write instruction (after the while loop). Only then will it release its lock on the file and will you be able to rename the file.
See: http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html#close()
I am trying to write an application in java that can pack a folder to a zip file. the user have to choose the folder with JFileChooser. When i try to pack it, it just creates a zip package with a conjunction to the folder that it should be. please can you tell me why and how to fix it?
LOLZ funny programming community, i just had to add "\\" instead of "/" while get the prefix length..
import java.io.*;
import java.util.zip.*;
import javax.swing.*;
import javax.swing.JFileChooser;
public class Zipper {
int prefixLength;
ZipOutputStream zipOut;
byte[] ioBuffer = new byte[4096];
public Zipper(String dirFileName, String dirFileOutput) throws Exception
{
prefixLength = dirFileName.lastIndexOf("/") + 1;
zipOut = new ZipOutputStream(new FileOutputStream(dirFileOutput + ".zip"));
createZipFrom(new File(dirFileName));
zipOut.close();
}
void createZipFrom(File dir) throws Exception
{ if (dir.exists() && dir.canRead() && dir.isDirectory())
{ File[] files = dir.listFiles();
if (files != null)
{ for (File file: files)
{ if (file.isDirectory())
{ createZipFrom(file);
}
else
{ String filePath = file.getAbsolutePath();
FileInputStream in = new FileInputStream(filePath);
zipOut.putNextEntry(new ZipEntry(filePath.substring(prefixLength)));
int bytesRead;
while ((bytesRead = in.read(ioBuffer)) > 0)
{ zipOut.write(ioBuffer, 0, bytesRead);
}
System.out.println(filePath + " added\n");
zipOut.closeEntry();
in.close();
}
}
}
}
}
public static void main(String[] args) throws Exception {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.showSaveDialog(null);
String path=chooser.getSelectedFile().getAbsolutePath();
String dirFileName=chooser.getSelectedFile().getAbsolutePath();
String dirFileOutput = JOptionPane.showInputDialog(null, "packetname"); // thats working..
System.out.println(dirFileName);
System.out.println(dirFileOutput);
new Zipper(dirFileName, dirFileOutput);
System.out.println("package " + dirFileOutput + "." + ".zip created\n");
}
}
I have written some utility methods using the NIO.2 File API, which makes zipping a folder easy. The library is Open Source. Maybe you find it usefull.
Tutorial: http://www.softsmithy.org/lib/0.4/docs/tutorial/nio-file/index.html#AddZipResourceSample
Javadoc: http://www.softsmithy.org/lib/0.4/docs/api/softsmithy-lib-core/index.html
Maven coordinates: http://search.maven.org/#artifactdetails|org.softsmithy.lib|softsmithy-lib-core|0.4|bundle
Is there any sample code, how to particaly unzip folder from ZIP into my desired directory? I have read all files from folder "FOLDER" into byte array, how do I recreate from its file structure?
I am not sure what do you mean by particaly?
Do you mean do it yourself without of API help?
In the case you don't mind using some opensource library,
there is a cool API for that out there called zip4J
It is easy to use and I think there is good feedback about it.
See this example:
String source = "folder/source.zip";
String destination = "folder/source/";
try {
ZipFile zipFile = new ZipFile(source);
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
If the files you want to unzip have passwords, you can try this:
String source = "folder/source.zip";
String destination = "folder/source/";
String password = "password";
try {
ZipFile zipFile = new ZipFile(source);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
I hope this is useful.
Here is the code I'm using. Change BUFFER_SIZE for your needs.
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public final class ZipUtils {
private static final int BUFFER_SIZE = 4096;
public static void extract(ZipInputStream zip, File target) throws IOException {
try {
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
File file = new File(target, entry.getName());
if (!file.toPath().normalize().startsWith(target.toPath())) {
throw new IOException("Bad zip entry");
}
if (entry.isDirectory()) {
file.mkdirs();
continue;
}
byte[] buffer = new byte[BUFFER_SIZE];
file.getParentFile().mkdirs();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
int count;
while ((count = zip.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.close();
}
} finally {
zip.close();
}
}
}
A most concise, library-free, Java 7+ variant:
public static void unzip(InputStream is, Path targetDir) throws IOException {
targetDir = targetDir.toAbsolutePath();
try (ZipInputStream zipIn = new ZipInputStream(is)) {
for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) {
Path resolvedPath = targetDir.resolve(ze.getName()).normalize();
if (!resolvedPath.startsWith(targetDir)) {
// see: https://snyk.io/research/zip-slip-vulnerability
throw new RuntimeException("Entry with an illegal path: "
+ ze.getName());
}
if (ze.isDirectory()) {
Files.createDirectories(resolvedPath);
} else {
Files.createDirectories(resolvedPath.getParent());
Files.copy(zipIn, resolvedPath);
}
}
}
}
The createDirectories is needed in both branches because zip files not always contain all the parent directories as a separate entries, but might contain them only to represent empty directories.
The code addresses the ZIP-slip vulnerability, it fails if some ZIP entry would go outside of the targetDir. Such ZIPs are not created using the usual tools and are very likely hand-crafted to exploit the vulnerability.
Same can be achieved using Ant Compress library. It will preserve the folder structure.
Maven dependency:-
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-compress</artifactId>
<version>1.2</version>
</dependency>
Sample code:-
Unzip unzipper = new Unzip();
unzipper.setSrc(theZIPFile);
unzipper.setDest(theTargetFolder);
unzipper.execute();
Here's an easy solution which follows more modern conventions. You may want to change the buffer size to be smaller if you're unzipping larger files. This is so you don't keep all of the files info in-memory.
public static void unzip(File source, String out) throws IOException {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) {
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
File file = new File(out, entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
int bufferSize = Math.toIntExact(entry.getSize());
byte[] buffer = new byte[bufferSize > 0 ? bufferSize : 1];
int location;
while ((location = zis.read(buffer)) != -1) {
bos.write(buffer, 0, location);
}
}
}
entry = zis.getNextEntry();
}
}
}
This is the code I used to unzip a zip file with multiple directories. No external libraries used.
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class UnzipFile
{
public static void main(String[] args) throws IOException
{
String fileZip = "src/main/resources/abcd/abc.zip";
File destDir = new File("src/main/resources/abcd/abc");
try (ZipFile file = new ZipFile(fileZip))
{
Enumeration<? extends ZipEntry> zipEntries = file.entries();
while (zipEntries.hasMoreElements())
{
ZipEntry zipEntry = zipEntries.nextElement();
File newFile = new File(destDir, zipEntry.getName());
//create sub directories
newFile.getParentFile().mkdirs();
if (!zipEntry.isDirectory())
{
try (FileOutputStream outputStream = new FileOutputStream(newFile))
{
BufferedInputStream inputStream = new BufferedInputStream(file.getInputStream(zipEntry));
while (inputStream.available() > 0)
{
outputStream.write(inputStream.read());
}
inputStream.close();
}
}
}
}
}
}
Here is more "modern" complete code based on this post but refactored (and using Lombok):
import lombok.var;
import lombok.val;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipInputStream;
import static java.nio.file.Files.createDirectories;
public class UnZip
{
public static void unZip(String sourceZipFile, String outputDirectory) throws IOException
{
val folder = new File(outputDirectory);
createDirectories(folder.toPath());
try (val zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile, Charset.forName("Cp437"))))
{
var nextEntry = zipInputStream.getNextEntry();
while (nextEntry != null)
{
val fileName = nextEntry.getName();
val newFile = new File(outputDirectory + File.separator + fileName);
newFile.getParentFile().mkdirs();
if(fileName.endsWith("/")){
newFile.mkdirs();
} else {
writeFile(zipInputStream, newFile);
}
writeFile(zipInputStream, newFile);
nextEntry = zipInputStream.getNextEntry();
}
zipInputStream.closeEntry();
}
}
private static void writeFile(ZipInputStream inputStream, File file) throws IOException
{
val buffer = new byte[1024];
file.createNewFile();
try (val fileOutputStream = new FileOutputStream(file))
{
int length;
while ((length = inputStream.read(buffer)) > 0)
{
fileOutputStream.write(buffer, 0, length);
}
}
}
}
After using the other libraries I stumbled upon this one: https://github.com/thrau/jarchivelib
Far superior.
Gradle: implementation group: 'org.rauschig', name: 'jarchivelib', version: '1.2.0'
import org.rauschig.jarchivelib.ArchiveFormat;
import org.rauschig.jarchivelib.Archiver;
import org.rauschig.jarchivelib.ArchiverFactory;
import org.rauschig.jarchivelib.CompressionType;
public static void unzip(File zipFile, File targetDirectory) throws IOException, IllegalAccessException {
Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP);
archiver.extract(zipFile, targetDirectory);
}
public static void unTarGz(File tarFile, File targetDirectory) throws IOException {
Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.GZIP);
archiver.extract(tarFile, targetDirectory);
}
The other libraries get too complex for this simple task. That's why I love this library - 2 lines, done.
You should get all entries from your zip file:
Enumeration entries = zipFile.getEntries();
Then iterating over this enumeration get the ZipEntry from it, check whether it is a directory or not, and create directory or just extract a file respectively.
Based on petrs's answer, here's a kotlin version, that I am now using:
fun ZipInputStream.extractTo(target: File) = use { zip ->
var entry: ZipEntry
while (zip.nextEntry.also { entry = it ?: return } != null) {
val file = File(target, entry.name)
if (entry.isDirectory) {
file.mkdirs()
} else {
file.parentFile.mkdirs()
zip.copyTo(file.outputStream())
}
}
}