Last active
December 22, 2015 07:08
-
-
Save edermag/6435674 to your computer and use it in GitHub Desktop.
Programa Java extrai um diretório contido em arquivo Zip
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static java.lang.System.currentTimeMillis; | |
import java.io.BufferedInputStream; | |
import java.io.BufferedOutputStream; | |
import java.io.File; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.util.Enumeration; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Queue; | |
import java.util.zip.ZipEntry; | |
import java.util.zip.ZipFile; | |
/** | |
* This class uses the Zip API from <code>java.util.zip</code>, to extract a content of directory. | |
* Inside a directory contains one or many files and sub-directories. | |
* | |
* <p>Example:</p> | |
* <blockquote><pre> | |
* ExtractZipDir.extract("/home/user/my.zip", "xdir"); | |
* </pre></blockquote> | |
* | |
* <p>Any error during the extract will be throws as a {@code}RuntimeException.<p> | |
* | |
* @see java.util.zip | |
* | |
* @author eder.magalhaes | |
*/ | |
public class ExtractZipDir { | |
public static void main(String[] args ) { | |
if (args.length < 2) { | |
System.out.println("Sorry... I need to know the zip name and the directory to extract."); | |
System.out.println("See how call this program:"); | |
System.out.println("\tExtractZipDir my.zip xdir"); | |
return; | |
} | |
String zipName = args[0]; | |
String dirName = args[1]; | |
extract(zipName, dirName); | |
} | |
static void extract(String zipName, String dirName) { | |
long before = currentTimeMillis(); | |
try (ZipFile zip = new ZipFile(new File(zipName))) { | |
ZipContent zContent = new ZipContent(zip); | |
int files = zContent.extract(dirName); | |
System.out.printf("Extract %s files (in %sms)", files, currentTimeMillis() - before); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
} | |
/** | |
* Encapsulate the zip content, in a <code>Map</code> collection. | |
*/ | |
private static class ZipContent { | |
private final ZipFile zip; | |
private Map<String, List<ZipEntry>> content = new HashMap<>(); | |
private int count; | |
private static final String SEPARATOR = "/"; | |
private static final String ROOT_DIRECTORY = "."; | |
private static final int BUFFER = 2048; | |
private ZipContent (ZipFile zipFile) { | |
zip = zipFile; | |
organizeEntries(zip.entries()); | |
} | |
private void organizeEntries(Enumeration<? extends ZipEntry> entries) { | |
putRootDir(); | |
while (entries.hasMoreElements()) { | |
ZipEntry entry = entries.nextElement(); | |
putEntry(entry); | |
} | |
} | |
private void putEntry(ZipEntry entry) { | |
String path = extractDirNameFromEntry(entry); | |
List<ZipEntry> entries = content.get(path); | |
if (entries == null) { | |
content.put(path, new LinkedList<ZipEntry>()); | |
} else { | |
entries.add(entry); | |
} | |
} | |
private void putRootDir() { | |
content.put(ROOT_DIRECTORY, new LinkedList<ZipEntry>()); | |
} | |
private List<ZipEntry> listContent(String folder) { | |
return content.get(folder); | |
} | |
private boolean hasDirectory(String folder) { | |
return content.keySet().contains(folder); | |
} | |
private Queue<String> getAllDirectoriesFromParent(String dir) { | |
Queue<String> q = new LinkedList<>(); | |
for (String d: content.keySet()) { | |
if (d.contains(dir) && !d.equals(dir)) | |
q.add(d); | |
} | |
q.add(dir); | |
return q; | |
} | |
private int extract(String dir) { | |
if (!dir.equals(ROOT_DIRECTORY)) { | |
if (!dir.endsWith(SEPARATOR)) { | |
dir = dir.concat(SEPARATOR); | |
} | |
if (!hasDirectory(dir)) { | |
throw new RuntimeException("Directory not found!"); | |
} | |
} | |
count = 0; | |
Queue<String> dirs = getAllDirectoriesFromParent(dir); | |
while (!dirs.isEmpty()) { | |
String path = dirs.poll(); | |
List<ZipEntry> entries = listContent(path); | |
File parent = new File(path); | |
parent.mkdirs(); | |
for (ZipEntry entry: entries) { | |
extract(parent, entry); | |
count++; | |
} | |
} | |
return count; | |
} | |
private void extract(File path, ZipEntry entry) { | |
String fileName = extractFilenameFromEntry(entry); | |
File destFile = new File(path, fileName); | |
try (BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry)); | |
FileOutputStream fos = new FileOutputStream(destFile); | |
BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) { | |
int currentByte; | |
byte data[] = new byte[BUFFER]; | |
while ((currentByte = is.read(data, 0, BUFFER)) != -1) { | |
dest.write(data, 0, currentByte); | |
} | |
dest.flush(); | |
} catch (IOException e) { | |
throw new RuntimeException("Not possible to extract!\n" + e.getMessage(), e); | |
} | |
} | |
private static String extractDirNameFromEntry(ZipEntry entry) { | |
String name = entry.getName(); | |
if (name.lastIndexOf(SEPARATOR) != -1) { | |
return name.substring(0, name.lastIndexOf(SEPARATOR)+1); | |
} | |
return ROOT_DIRECTORY; | |
} | |
private static String extractFilenameFromEntry(ZipEntry entry) { | |
String name = entry.getName(); | |
if (name.lastIndexOf(SEPARATOR) == -1) { | |
return name; | |
} | |
return name.substring(name.lastIndexOf(SEPARATOR)+1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment