/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.aliyun.odps.local.common.utils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
public class ArchiveUtils {
public static void unArchive(File inFile, File outDir) throws IOException {
try {
String name = inFile.getName().toLowerCase();
if (name.endsWith(".zip")) {
unZip(inFile, outDir);
} else if (name.endsWith(".jar")) {
unJar(inFile, outDir);
} else if (name.endsWith(".tar.gz") || name.endsWith(".tgz")) {
unGZip(inFile, outDir);
} else if (name.endsWith(".tar")) {
unTar(inFile, outDir);
}
} catch (ArchiveException ex) {
throw new IOException(ex);
}
}
@SuppressWarnings("rawtypes")
public static void unJar(File jarFile, File toDir) throws IOException {
JarFile jar = new JarFile(jarFile);
try {
Enumeration entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = (JarEntry) entries.nextElement();
if (!entry.isDirectory()) {
InputStream in = jar.getInputStream(entry);
try {
File file = new File(toDir, entry.getName());
if (!file.getParentFile().mkdirs()) {
if (!file.getParentFile().isDirectory()) {
throw new IOException("Mkdirs failed to create "
+ file.getParentFile().toString());
}
}
OutputStream out = new FileOutputStream(file);
try {
byte[] buffer = new byte[8192];
int i;
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
} finally {
jar.close();
}
}
/**
* Given a File input it will unzip the file in a the unzip directory passed
* as the second parameter
*
* @param inFile
* The zip file as input
* @param unzipDir
* The unzip directory where to unzip the zip file.
* @throws IOException
*/
public static void unZip(File inFile, File unzipDir) throws IOException {
Enumeration<? extends ZipEntry> entries;
ZipFile zipFile = new ZipFile(inFile);
try {
entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
InputStream in = zipFile.getInputStream(entry);
try {
File file = new File(unzipDir, entry.getName());
if (!file.getParentFile().mkdirs()) {
if (!file.getParentFile().isDirectory()) {
throw new IOException("Mkdirs failed to create "
+ file.getParentFile().toString());
}
}
OutputStream out = new FileOutputStream(file);
try {
byte[] buffer = new byte[8192];
int i;
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
} finally {
zipFile.close();
}
}
public static void unTar(File inFile, File untarDir) throws IOException,
ArchiveException {
final InputStream is = new FileInputStream(inFile);
final TarArchiveInputStream in = (TarArchiveInputStream) new ArchiveStreamFactory()
.createArchiveInputStream(ArchiveStreamFactory.TAR, is);
TarArchiveEntry entry = null;
untarDir.mkdirs();
while ((entry = (TarArchiveEntry) in.getNextEntry()) != null) {
byte[] content = new byte[(int) entry.getSize()];
in.read(content);
final File entryFile = new File(untarDir, entry.getName());
if (entry.isDirectory() && !entryFile.exists()) {
if (!entryFile.mkdirs()) {
throw new IOException("Create directory failed: "
+ entryFile.getAbsolutePath());
}
} else {
final OutputStream out = new FileOutputStream(entryFile);
IOUtils.write(content, out);
out.close();
}
}
in.close();
}
public static void unGZip(File gzFile, File ungzipDir) throws IOException,
ArchiveException {
String gzFileName = gzFile.getName();
String tarFileName = "";
if (gzFileName.endsWith(".tar.gz")) {
tarFileName = gzFileName.substring(0, gzFileName.length() - 3);// 3 is length of '.gz'
} else if (gzFileName.endsWith(".tgz")) {
tarFileName = gzFileName.substring(0, gzFileName.length() - 4) + ".tar";// 4 is length of
// '.tgz'
}
File tarFile = new File(gzFile.getParentFile(), tarFileName);
FileOutputStream tarOut = new FileOutputStream(tarFile);
GzipCompressorInputStream gzIn = new GzipCompressorInputStream(
new BufferedInputStream(new FileInputStream(gzFile)));
IOUtils.copy(gzIn, tarOut);
tarOut.close();
gzIn.close();
unTar(tarFile, ungzipDir);
// remove the temporary tarFile
FileUtils.deleteQuietly(tarFile);
}
}