方法一
public class Decompression {
private static final Logger LOGGER = Logger.getLogger(Decompression.class);
private static final int BUFFER = 512;
private static final int TOO_BIG = 0x6400000;
private static final int TOO_MANY = 1024;
private Decompression() {
}
public static void zipUncompress(String inputFile, String destDirPath) {
FileOutputStream fileOutputStream = null;
InputStream inputStream = null;
ZipFile zipFile = null;
try {
File srcFile = new File(inputFile);
if (!srcFile.exists()) {
throw new IOException(srcFile.getPath());
}
zipFile = new ZipFile(srcFile);
Enumeration entries = zipFile.entries();
int total = 0;
int entriesNumber = 0;
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
checkFileName(entry.getName(), destDirPath);
int count = 0;
if (entry.isDirectory()) {
if (!srcFile.mkdir()) {
throw new IOException();
}
} else {
String fileName = Tools.delTimeStamp(entry.getName());
File targetFile = new File(destDirPath + File.separator + fileName);
if (!targetFile.getParentFile().exists()) {
if (targetFile.getParentFile().mkdirs()) {
throw new IOException();
}
}
if (!targetFile.createNewFile()) {
throw new IOException();
}
inputStream = zipFile.getInputStream(entry);
fileOutputStream = new FileOutputStream(targetFile);
int len;
byte[] buf = new byte[BUFFER];
while ((len = inputStream.read(buf)) != -1) {
total += count;
if (total > TOO_BIG) {
LOGGER.error("Zip file is too big.");
break;
}
fileOutputStream.write(buf, 0, len);
}
entriesNumber++;
if (total > TOO_BIG) {
LOGGER.error("Zip file is too big.");
break;
}
if (entriesNumber > TOO_MANY) {
LOGGER.error("Zip file is too many.");
break;
}
}
}
} catch (IOException e) {
LOGGER.error("IOException error.", e);
} finally {
closeProcess(inputFile, fileOutputStream, inputStream, zipFile);
}
}
private static String checkFileName(String entryName, String intendedDir) throws IOException {
File file = new File(intendedDir, entryName);
String canonicalPath1 = file.getCanonicalPath();
File intendedFile = new File(intendedDir);
String canonicalPath2 = intendedFile.getCanonicalPath();
if (canonicalPath1.startsWith(canonicalPath2)) {
return canonicalPath1;
} else {
throw new IllegalStateException();
}
}
private static void closeProcess(String inputFile, FileOutputStream fileOutputStream, InputStream inputStream,
ZipFile zipFile) {
try {
if (zipFile != null) {
zipFile.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (inputFile != null) {
inputStream.close();
}
} catch (IOException e) {
LOGGER.error("Close error.", e);
}
}
}
方法二
public class Decompression {
private static final Logger LOGGER = Logger.getLogger(Decompression.class);
private static final int BUFFER = 512;
private static final int TOO_BIG = 0x6400000;
private static final int TOO_MANY = 1024;
private Decompression() {
}
public static void zipUncompress(String inputFile, String destDirPath) {
FileOutputStream fileOutputStream = null;
InputStream inputStream = null;
ZipFile zipFile = null;
try {
File srcFile = new File(inputFile);
if (!srcFile.exists()) {
throw new IOException(srcFile.getPath());
}
zipFile = new ZipFile(srcFile);
Enumeration entries = zipFile.entries();
int total = 0;
int entriesNumber = 0;
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
checkFileName(entry.getName(), destDirPath);
int count = 0;
if (entry.isDirectory()) {
if (!srcFile.mkdir()) {
throw new IOException();
}
} else {
String fileName = Tools.delTimeStamp(entry.getName());
File targetFile = new File(destDirPath + File.separator + fileName);
if (!targetFile.getParentFile().exists()) {
if (targetFile.getParentFile().mkdirs()) {
throw new IOException();
}
}
if (!targetFile.createNewFile()) {
throw new IOException();
}
inputStream = zipFile.getInputStream(entry);
fileOutputStream = new FileOutputStream(targetFile);
int len;
byte[] buf = new byte[BUFFER];
while ((len = inputStream.read(buf)) != -1) {
total += count;
if (total > TOO_BIG) {
LOGGER.error("Zip file is too big.");
break;
}
fileOutputStream.write(buf, 0, len);
}
entriesNumber++;
if (total > TOO_BIG) {
LOGGER.error("Zip file is too big.");
break;
}
if (entriesNumber > TOO_MANY) {
LOGGER.error("Zip file is too many.");
break;
}
}
}
} catch (IOException e) {
LOGGER.error("IOException error.", e);
} finally {
closeProcess(inputFile, fileOutputStream, inputStream, zipFile);
}
}
private static String checkFileName(String entryName, String intendedDir) throws IOException {
File file = new File(intendedDir, entryName);
String canonicalPath1 = file.getCanonicalPath();
File intendedFile = new File(intendedDir);
String canonicalPath2 = intendedFile.getCanonicalPath();
if (canonicalPath1.startsWith(canonicalPath2)) {
return canonicalPath1;
} else {
throw new IllegalStateException();
}
}
private static void closeProcess(String inputFile, FileOutputStream fileOutputStream, InputStream inputStream,
ZipFile zipFile) {
try {
if (zipFile != null) {
zipFile.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (inputFile != null) {
inputStream.close();
}
} catch (IOException e) {
LOGGER.error("Close error.", e);
}
}
}