要用java 壓縮多級文件夾&文件. 整理出一個可用的工具類,有問題,請及時聯繫.
壓縮文件夾:
CompressUtil.compress
解壓 tar.gz 文件:
CompressUtil.decompress
maven 依賴:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.18</version>
</dependency>
代碼:
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class CompressUtil {
public static void main(String[] args) throws Exception {
// 壓縮文件
// CompressUtil.compress("/a/tmp/tmp/test","/a/tmp/tmp/tar/","test");
// 解壓文件
CompressUtil.decompress("/a/tmp/tmp/tar/test.tar.gz","/a/tmp/tmp/tar");
}
private static final int BUFFER_SIZE = 1024 * 100;
private CompressUtil() {
}
public static List<File> getFiles(String path) {
List<File> list = new LinkedList<File>();
File file = new File(path);
File[] tempList = file.listFiles();
if(null != tempList && tempList.length>0){
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile()) {
list.add(new File(tempList[i].getPath()));
}
if (tempList[i].isDirectory()) {
List tmpList = getFiles(tempList[i].getPath());
if(null !=tmpList && tmpList.size()>0){
list.addAll(tmpList);
}
}
}
}
return list;
}
/**
* 私有函數將文件集合壓縮成tar包後返回
*
* @param files 要壓縮的文件集合
* @param target tar 輸出流的目標文件
* @return File 指定返回的目標文件
*/
public static File pack(List<File> files,String inPutPath, File target) throws IOException {
try (FileOutputStream out = new FileOutputStream(target)) {
try (BufferedOutputStream bos = new BufferedOutputStream(out, BUFFER_SIZE)) {
TarArchiveOutputStream os = new TarArchiveOutputStream(bos);
try {
//解決文件名過長問題
os.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
for (File file : files) {
//去掉文件前面的目錄
os.putArchiveEntry(new TarArchiveEntry(file, file.getAbsolutePath().replace(inPutPath,"")));
try (FileInputStream fis = new FileInputStream(file)) {
IOUtils.copy(fis, os);
os.closeArchiveEntry();
}
}
}catch (Exception e){
e.printStackTrace();
}finally {
os.close();
}
}
}
return target;
}
public static void compress(String source , String target,String fileName) throws Exception {
List<File> list = getFiles(source);
if(list.size()<=0){
System.out.println("source file is empty , please check [ "+source+" ]....");
return;
}
File file = new File(target);
if(!file.exists()){
file.mkdirs();
}
compressTar(list,source,target,fileName);
}
/**
* 壓縮tar文件
*
* @param list
* @param outPutPath
* @param fileName
*/
public static File compressTar(List<File> list,String inPutPath, String outPutPath, String fileName) throws Exception {
File outPutFile = new File(outPutPath + File.separator + fileName + ".tar.gz");
File tempTar = new File("temp.tar");
try (FileInputStream fis = new FileInputStream(pack(list,inPutPath, tempTar))) {
try (BufferedInputStream bis = new BufferedInputStream(fis, BUFFER_SIZE)) {
try (FileOutputStream fos = new FileOutputStream(outPutFile)) {
try (GZIPOutputStream gzp = new GZIPOutputStream(fos)) {
int count;
byte[] data = new byte[BUFFER_SIZE];
while ((count = bis.read(data, 0, BUFFER_SIZE)) != -1) {
gzp.write(data, 0, count);
}
}
}
}
}
try {
Files.deleteIfExists(tempTar.toPath());
} catch (IOException e) {
e.printStackTrace();
}
return outPutFile;
}
public static boolean decompress(String filePath, String outputDir) {
File file = new File(filePath);
if (!file.exists()) {
System.out.println("decompress file not exist.");
return false;
}
try {
if (filePath.endsWith(".zip")) {
unZip(file, outputDir);
}
if (filePath.endsWith(".tar.gz") || filePath.endsWith(".tgz")) {
decompressTarGz(file, outputDir);
}
if (filePath.endsWith(".tar.bz2")) {
decompressTarBz2(file, outputDir);
}
filterFile(new File(outputDir));
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
/**
* 解壓 .zip 文件
*
* @param file 要解壓的zip文件對象
* @param outputDir 要解壓到某個指定的目錄下
* @throws IOException
*/
public static void unZip(File file, String outputDir) throws IOException {
try (ZipFile zipFile = new ZipFile(file, StandardCharsets.UTF_8)) {
//創建輸出目錄
createDirectory(outputDir, null);
Enumeration<?> enums = zipFile.entries();
while (enums.hasMoreElements()) {
ZipEntry entry = (ZipEntry) enums.nextElement();
if (entry.isDirectory()) {
//創建空目錄
createDirectory(outputDir, entry.getName());
} else {
try (InputStream in = zipFile.getInputStream(entry)) {
try (OutputStream out = new FileOutputStream(
new File(outputDir + File.separator + entry.getName()))) {
writeFile(in, out);
}
}
}
}
}
}
public static void decompressTarGz(File file, String outputDir) throws IOException {
try (TarArchiveInputStream tarIn = new TarArchiveInputStream(
new GzipCompressorInputStream(
new BufferedInputStream(
new FileInputStream(file))))) {
//創建輸出目錄
createDirectory(outputDir, null);
TarArchiveEntry entry = null;
while ((entry = tarIn.getNextTarEntry()) != null) {
//是目錄
if (entry.isDirectory()) {
//創建空目錄
createDirectory(outputDir, entry.getName());
} else {
//是文件
try (OutputStream out = new FileOutputStream(
new File(outputDir + File.separator + entry.getName()))) {
writeFile(tarIn, out);
}
}
}
}
}
/**
* 解壓縮tar.bz2文件
*
* @param file 壓縮包文件
* @param outputDir 目標文件夾
*/
public static void decompressTarBz2(File file, String outputDir) throws IOException {
try (TarArchiveInputStream tarIn =
new TarArchiveInputStream(
new BZip2CompressorInputStream(
new FileInputStream(file)))) {
createDirectory(outputDir, null);
TarArchiveEntry entry;
while ((entry = tarIn.getNextTarEntry()) != null) {
if (entry.isDirectory()) {
createDirectory(outputDir, entry.getName());
} else {
try (OutputStream out = new FileOutputStream(
new File(outputDir + File.separator + entry.getName()))) {
writeFile(tarIn, out);
}
}
}
}
}
/**
* 寫文件
*
* @param in
* @param out
* @throws IOException
*/
public static void writeFile(InputStream in, OutputStream out) throws IOException {
int length;
byte[] b = new byte[BUFFER_SIZE];
while ((length = in.read(b)) != -1) {
out.write(b, 0, length);
}
}
/**
* 創建目錄
*
* @param outputDir
* @param subDir
*/
public static void createDirectory(String outputDir, String subDir) {
File file = new File(outputDir);
//子目錄不爲空
if (!(subDir == null || subDir.trim().equals(""))) {
file = new File(outputDir + File.separator + subDir);
}
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.mkdirs();
}
}
/**
* 刪除Mac壓縮再解壓產生的 __MACOSX 文件夾和 .開頭的其他文件
*
* @param filteredFile
*/
public static void filterFile(File filteredFile) {
if (filteredFile != null) {
File[] files = filteredFile.listFiles();
for (File file : files) {
if (file.getName().startsWith(".") ||
(file.isDirectory() && file.getName().equals("__MACOSX"))) {
FileUtils.deleteQuietly(file);
}
}
}
}
}