標籤:return 子目錄 mcr example path pat utils throw star
本文介紹Java解壓縮.zip、.tar.gz、.tar.bz2的方式。
- 對於zip檔案:使用
java.util.zip.ZipEntry 和 java.util.zip.ZipFile,通過設定Charset為StandardCharsets.UTF_8支援中文。
- 對於.tar.gz、tgz檔案:可以看做先用tar打包,再使用gz進行壓縮。使用
commons-compress包的TarArchiveInputStream和GzipCompressorInputStream。
- 對於.tar.bz2檔案:可以看做先用tar打包,再使用bz2進行壓縮。使用
commons-compress包的TarArchiveInputStream和BZip2CompressorInputStream。
在這裡有個問題如果使用TarInputStream搭配jdk的 GZIPInputStream會產生亂碼。而使用commons-compress包的TarArchiveInputStream和GzipCompressorInputStream則可解決亂碼問題。
代碼如下:
public class ZipUtil { private static final Logger LOG = LoggerFactory.getLogger(ZipUtil.class); private static final int BUFFER_SIZE = 1024 * 100; private ZipUtil() { } public static boolean decompress(String filePath, String outputDir, boolean isDeleted) { File file = new File(filePath); if (!file.exists()) { LOG.error("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)); if (isDeleted) { FileUtils.deleteQuietly(file); } return true; } catch (IOException e) { LOG.error("decompress occur error."); } 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); } } } }}
代碼地址
參考文檔:
- commons-compress官方執行個體
Java解壓縮.zip、.tar.gz、.tar.bz2(支援中文)