压缩和解压缩依赖
导入pom依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
rar的pom依赖为
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
</dependency>
关于Java解压Zip文件的java.lang.IllegalArgumentException:MALFORMED报错问题。
java报错
java.lang.IllegalArgumentException:MALFORMED
at java.util.zip.ZipCoder.toString(ZipCoder.toString:58)
......
首先在网上查了下这个异常的原因, 都说是因为编码的问题, 要求将UTF-8改成GBK就可以了。 然后找到ZipCoder.toString方法的58行
String toString(byte[] ba, int length) {
CharsetDecoder cd = decoder().reset();
int len = (int)(length * cd.maxCharsPerByte());
char[] ca = new char[len];
if (len == 0)
return new String(ca);
if (isUTF8 && cd instanceof ArrayDecoder) {
int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
if (clen == -1)
throw new IllegalArgumentException("MALFORMED");
return new String(ca, 0, clen);
}
ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
CharBuffer cb = CharBuffer.wrap(ca);
CoderResult cr = cd.decode(bb, cb, true);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
cr = cd.flush(cb);
if (!cr.isUnderflow())
throw new IllegalArgumentException(cr.toString());
return new String(ca, 0, cb.position());
}
这里只有UTF-8才会进入if逻辑才会抛出异常?果然如网上所说, 将编码格式改为GBK即可。 ZipCoder这个是src.zip包中的, 既然这里做了校验当然会有它的道理。 但是,单纯的改为GBK来解决这个bug显然是不合理的。 于是又在网上找,将原来写的 ZipInputStream 改为 ZipArchiveInputStream ; ZipEntry 改为 ZipArchiveEntry ; zipin.getNextEntry() 改为 zipin.getNextZipEntry() 可解决问题。
解压缩代码
Zip解压缩
public class ZipUtil {
private static final Logger log = LoggerFactory.getLogger(ZipUtil.class);
public static void doUnzip(String fileName) throws Exception {
File f = new File(fileName);
String fileDir = f.getParent();
log.debug("path is {}", fileDir);
doUnzip(fileName, fileDir);
}
public static void doUnzip(String fileName, String dir) throws Exception {
try ( FileInputStream fi = new FileInputStream(fileName);) {
doUnzip(fi, dir);
}
}
public static void doUnzip(File file, String dir) throws Exception {
try ( FileInputStream fi = new FileInputStream(file);) {
doUnzip(fi, dir);
}
}
public static void doUnzip(InputStream fi, final String dir) throws Exception {
try (
CheckedInputStream csi = new CheckedInputStream(fi, new Adler32());
ZipArchiveInputStream zipin = new ZipArchiveInputStream(csi)) {
ZipArchiveEntry ze;
while ((ze = zipin.getNextZipEntry()) != null) {
String name = ze.getName();
log.debug("name is {}", name);
File newFile = UtilFile.newFileWithCheck(dir, name);
if (ze.isDirectory()) {
if (!newFile.exists()) {
newFile.mkdirs();
}
} else {
if (!newFile.getParentFile().exists()) {
newFile.getParentFile().mkdirs();
}
try ( OutputStream out = new FileOutputStream(newFile);) {
UtilFile.copyNoClose(zipin, out);
}
}
}
}
}
public static final File newFileWithCheck(final String destinationDirName, final String name) throws IOException {
File destinationDir = new File(destinationDirName);
return newFileWithCheck(destinationDir, name);
}
public static final File newFileWithCheck(final File destinationDir, final String name) throws IOException {
File destFile = new File(destinationDir, name);
String destDirPath = destinationDir.getCanonicalPath();
String destFilePath = destFile.getCanonicalPath();
if (!destFilePath.startsWith(destDirPath + File.separator)) {
throw new IOException("Entry is outside of the target dir: " + name);
}
return destFile;
}
public final static void copyNoClose(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[BufferSize << 1];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
out.flush();
}
}
War解压缩
public class WarUtil {
private static final Logger logger = LoggerFactory.getLogger(WarUtil.class);
private static FileNameExtensionFilter filter = new FileNameExtensionFilter(
"WAR压缩文件(*.war)", "war");
public static void unCompressWar(String filePath, String destPath) throws IOException, ArchiveException {
unCompressWar(new FileInputStream(filePath),destPath);
}
public static void unCompressWar(File srcFile, String destPath) throws IOException, ArchiveException {
unCompressWar(new FileInputStream(srcFile),destPath);
}
public static void unCompressWar(InputStream warInputStream, String destPath) throws IOException, ArchiveException {
ArchiveInputStream in = null;
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(warInputStream);
in = new ArchiveStreamFactory().createArchiveInputStream(ArchiveStreamFactory.JAR, bufferedInputStream);
JarArchiveEntry entry = null;
logger.info("解压文件: 到 {}", destPath);
while ((entry = (JarArchiveEntry) in.getNextEntry()) != null) {
if (entry.isDirectory()) {
File newFile = UtilFile.newFileWithCheck(destPath, entry.getName());
if(!newFile.exists()){
logger.info("文件夹{}不存在,创建.",newFile.getAbsolutePath());
newFile.mkdir();
}
if(newFile.exists() && !newFile.isDirectory()){
logger.info("不能解压文件{}到{},此文件己存在",entry.getName(),newFile.getAbsolutePath());
}
} else {
File outFile = UtilFile.newFileWithCheck(destPath, entry.getName());
if(!outFile.getParentFile().exists()){
logger.info("文件夹{}不存在,创建.",outFile.getParentFile().getAbsolutePath());
outFile.getParentFile().mkdirs();
}
logger.info("解压{} 至 {}",entry.getName(),outFile.getAbsolutePath());
OutputStream out = FileUtils.openOutputStream(outFile);
IOUtils.copy(in, out);
out.close();
}
}
} catch (FileNotFoundException e) {
logger.error("未找到war文件");
throw new FileNotFoundException("未找到war文件");
} catch (ArchiveException e) {
logger.error("不支持的压缩格式");
throw new ArchiveException("不支持的压缩格式");
} catch (IOException e) {
logger.error("文件写入发生错误");
throw new IOException("文件写入发生错误");
}finally{
in.close();
logger.info("解压结束.");
}
}
public FileNameExtensionFilter getFileFilter() {
return filter;
}
}
Tar解压缩
public class TarUtil {
public static void unCompressTar(String srcfilePath, String destpath)
throws IOException {
unCompressTar(new FileInputStream(srcfilePath), destpath);
}
public static void unCompressTar(File srcfile, String destpath)
throws IOException {
unCompressTar(new FileInputStream(srcfile), destpath);
}
public static void unCompressTar(InputStream inputStream, String destPath)
throws IOException {
BufferedInputStream bis = new BufferedInputStream(inputStream);
TarArchiveInputStream taris = new TarArchiveInputStream(bis);
TarArchiveEntry entry = null;
while ((entry = taris.getNextTarEntry()) != null) {
File newFile = UtilFile.newFileWithCheck(destPath, entry.getName());
if (entry.isDirectory()) {
newFile.mkdirs();
} else {
File parent = newFile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
FileOutputStream fos = new FileOutputStream(newFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int len;
byte[] buf = new byte[1024];
while ((len = taris.read(buf)) != -1) {
bos.write(buf, 0, len);
}
bos.flush();
bos.close();
}
}
taris.close();
}
}
TarGz解压缩
public class TarGzUtil {
private static final Logger logger = LoggerFactory.getLogger(TarGzUtil.class);
public static void unCompressTarGz(String sourcePath, String destPath) throws IOException {
long start = System.currentTimeMillis();
File sourceFile = new File(sourcePath);
logger.info("start to unpack tar.gz file, file name:{}", sourceFile.getName());
unCompressTarGz(sourceFile, destPath);
logger.info("finish unpack tar.gz file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start);
}
public static void unCompressTarGz(File sourceFile, String destPath) throws IOException {
long start = System.currentTimeMillis();
logger.info("start to unpack tar.gz file, file name:{}", sourceFile.getName());
unCompressTarGz(new FileInputStream(sourceFile), destPath);
logger.info("finish unpack tar.gz file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start);
}
public static void unCompressTarGz(InputStream inputStream, String destPath) throws IOException {
logger.info("start to unpack tar.gz fileInputStream");
try (FileInputStream fileInputStream = (FileInputStream) inputStream;
GzipCompressorInputStream gzipCompressorInputStream = new GzipCompressorInputStream(fileInputStream);
TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipCompressorInputStream, "UTF-8")) {
TarArchiveEntry entry;
while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) {
if (entry.isDirectory()) {
continue;
}
File curFile = UtilFile.newFileWithCheck(destPath, entry.getName());
File parent = curFile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
try (FileOutputStream outputStream = new FileOutputStream(curFile)) {
IOUtils.copy(tarArchiveInputStream, outputStream);
}
}
}
logger.info("finish unpack tar.gz file");
}
}
Rar解压缩
rar解压缩暂不支持高版本的解压缩
public class RarUtil {
private static final Logger logger = LoggerFactory.getLogger(RarUtil.class);
public static void unCompressRar(String sourcePath, String targetPath) {
unCompressRar(new File(sourcePath), targetPath);
}
public static void unCompressRar(File sourceFile, String targetPath) {
logger.info("start to unpack rar file, file name:{}", sourceFile.getName());
long start = System.currentTimeMillis();
System.out.println("absolute path is ============= " + sourceFile.getAbsolutePath());
try (Archive archive = new Archive(new FileInputStream(sourceFile))) {
FileHeader fileHeader = archive.nextFileHeader();
while (fileHeader != null) {
if (fileHeader.isDirectory()) {
fileHeader = archive.nextFileHeader();
continue;
}
File out = new File(String.format("%s%s%s", targetPath, File.separator, fileHeader.getFileName()));
if (!out.exists()) {
if (!out.getParentFile().exists()) {
out.getParentFile().mkdirs();
}
out.createNewFile();
}
try (FileOutputStream os = new FileOutputStream(out)) {
archive.extractFile(fileHeader, os);
} catch (RarException e) {
logger.error("unpack rar throw exception, filename:{}, e:{}", sourceFile.getName(), e);
}
fileHeader = archive.nextFileHeader();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (RarException e) {
logger.error("unpack rar throw exception, file name:{}, e:{}", sourceFile.getName(), e);
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
logger.info("finish unpack rar file, file name:{}, cost:{} ms", sourceFile.getName(), System.currentTimeMillis() - start);
}
}
|