public class ExtractZipDir {
public static void main(String[] args ) {
if (args.length < 2) {
System.out.println("Informe o arquivo zip e a pasta");
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("Extraiu %s arquivos (e, %sms)", files,
currentTimeMillis() - before);
} catch (Exception ex) {
ex.printStackTrace();
}
}
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 e) {
String fileName = extractFilenameFromEntry(e);
File destFile = new File(path, fileName);
try (BufferedInputStream is = new BufferedInputStream(zip.getInputStream(e));
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("Não foi possível extrair!\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);
}
}
}
Alguns formas de como executar esse programa (Linux / Windows):
$ java ExtractZipDir /home/user/meu.zip dir $ java C:\usuario\Documents\meu.zip dir
Compartilhei esse código no github.
@edermag
No comments:
Post a Comment