使用Java 代码实现,压缩东西到.tar.gz文件里面,或者使用代码解压.tar.gz文件

目录

  • 1 问题
  • 2 实现(工具类)

1 问题

使用Java 代码实现,压缩东西到.tar.gz文件里面,或者使用代码解压.tar.gz文件

2 实现(工具类)

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * 把一个目录下的所有文件和文件夹打成.tar.gz包(从当前的目录开始)
 * @time 16:15
 * @discription
 **/
@Slf4j
public class TarUtil {

//    private static void main(String[] args) throws IOException {


    /**
     * 把多个文件夹打成.tar.gz包(从当前的目录开始)
     * @param sourceFolder 需要打成.tar.gz包的目录列表(包含目录和目录下的所有文件和文件夹)
     * @param tarGzPath  打成的tar包生成的目标目录 例: D:/tmp  最终打包会在 D:/tmp目录下生成 test.tar.gz包
     * @param tarGzFileName 打tar.gz包的名,例如:ide-sdk.tar.gz
     */
    public static void fileListToTar(List sourceFolder, String tarGzPath, String tarGzFileName) {
        TarArchiveOutputStream tarOs = null;
        try {
            //            遍历每一个文件的绝对路径
            for(String folder : sourceFolder){
                if(folder.contains("../")){
                    throw new FileNotFoundException("压缩的目录不存在。。。");
                }
                File sourceFile = new File(folder);
                if (!sourceFile.exists()) {
                    throw new FileNotFoundException("压缩的目录不存在。。。");
                }
            }
            // 压缩包流
            tarOs = createTar(tarGzPath,tarGzFileName,tarOs);
            // 遍历每一个文件的绝对路径
            for(String folder : sourceFolder){
                addFileListToTarGZ(folder, tarOs);
            }
        } catch (IOException e) {
            log.info(e.getMessage());
        } finally {
            try {
                tarOs.close();
            } catch (IOException e) {
                log.info(e.getMessage());
            }
        }
    }

    /**
     * 把文件复制到.tar.gz包中
     * @param sourceFile 需要复制的文件路径
     * @param tarArchive tar包流
     * @throws IOException 异常
     */
    private static void addFileListToTarGZ(String sourceFile, TarArchiveOutputStream tarArchive)
            throws IOException {
        //        原文件绝对路径
        if(sourceFile.contains("../")){
            throw new FileNotFoundException("文件不存在。。。");
        }

        File file = new File(sourceFile);
        String parent = file.getParent();
        //        String entryName = parent +File.separator+ file.getName();
        String entryName = file.getName();
        // 添加 tar ArchiveEntry
        tarArchive.putArchiveEntry(new TarArchiveEntry(file, entryName));
        if (file.isFile()) {
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            // 写入文件
            IOUtils.copy(bis, tarArchive);
            tarArchive.closeArchiveEntry();
            bis.close();
        }
    }

    /**
     * 把一个目录下的所有文件和文件夹打成.tar.gz包(从当前的目录开始)
     * 

Method :createTarFile *

Description : 打包文件 .tar.gz * * @param sourceFolder 需要打成.tar.gz包的目录(包含目录和目录下的所有文件和文件夹)例:E:/aarm/test * @param tarGzPath 打成的tar包生成的目标目录 例: D:/tmp 最终打包会在 D:/tmp目录下生成 test.tar.gz包 * @param tarGzFileName 打tar.gz包的名,例如:ide-sdk.tar.gz */ public static void fileToTar(String sourceFolder, String tarGzPath, String tarGzFileName) { TarArchiveOutputStream tarOs = null; try { File sourceFile = new File(sourceFolder); if (!sourceFile.exists()) { throw new FileNotFoundException("压缩的目录不存在。。。"); } tarOs = createTar(tarGzPath,tarGzFileName,tarOs); String fileDir = sourceFolder.split(File.separator)[sourceFolder.split(File.separator).length-1]; String tarDir = tarGzFileName.split("\\.")[0]; String name = fileDir+"_"+tarDir; addFilesToTarGZ(sourceFile, "", tarOs,name); } catch (IOException e) { log.info(e.getMessage()); } finally { try { tarOs.close(); } catch (IOException e) { log.info(e.getMessage()); } } } /** * 把文件复制到.tar.gz包中 * @param file 需要复制的文件 * @param parent 父目录 * @param tarArchive tar包流 * @param tarDir 旧文件最后一级目录_包名目录 * @throws IOException 异常 */ private static void addFilesToTarGZ(File file, String parent, TarArchiveOutputStream tarArchive,String tarDir) throws IOException { // 将最外层的文件夹名,默认为包名 if(parent.startsWith(tarDir.split("_")[0]+ File.separator)) { parent = parent.replace(parent, tarDir.split("_")[1]+File.separator); } String entryName = parent + file.getName(); if(!parent.equals("")) { // 添加 tar ArchiveEntry tarArchive.putArchiveEntry(new TarArchiveEntry(file, entryName)); } if (file.isFile()) { // 确认是否为file对象 FileInputStream fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis); // 写入文件 IOUtils.copy(bis, tarArchive); tarArchive.closeArchiveEntry(); bis.close(); } else if (file.isDirectory()) { // 检查一个对象是否为文件夹 // 因为是个文件夹,无需写入内容,关闭即可 if(!parent.equals("")) { tarArchive.closeArchiveEntry(); } File[] files = file.listFiles(); if (files != null) { // 读取文件夹下所有文件 for (File f : files) { // 递归 addFilesToTarGZ(new File(f.getAbsolutePath()), entryName + File.separator, tarArchive,tarDir); } } } } /** * 创建tar包的流 * @param tarGzPath 需要复制的文件路径 * @param tarGzFileName 文件名称 * @param tarOs tar包流 * @throws IOException 异常 */ private static TarArchiveOutputStream createTar(String tarGzPath, String tarGzFileName,TarArchiveOutputStream tarOs) throws IOException { // 原文件绝对路径 if(tarGzPath.contains("../")){ throw new FileNotFoundException("文件不存在。。。"); } File tarGzFile = new File(tarGzPath); if (!tarGzFile.exists()) { tarGzFile.mkdirs(); } // 创建一个 FileOutputStream 到输出文件(.tar.gz) File tarFile = new File(tarGzFile + "/" + tarGzFileName); // File tarFile = new File(tarGzFile + tarGzFileName); FileOutputStream fos = new FileOutputStream(tarFile); // 创建一个 GZIPOutputStream,用来包装 FileOutputStream 对象 GZIPOutputStream gos = new GZIPOutputStream(new BufferedOutputStream(fos)); // 创建一个 TarArchiveOutputStream,用来包装 GZIPOutputStream 对象 tarOs = new TarArchiveOutputStream(gos); // 若不设置此模式,当文件名超过 100 个字节时会抛出异常,异常大致如下: // is too long ( > 100 bytes) // 具体可参考官方文档:http://commons.apache.org/proper/commons-compress/tar.html#Long_File_Names tarOs.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); return tarOs; } /** * 解压.tar.gz文件 * @param sourceFile 需解压文件 * @param outputDir 输出目录 * @throws IOException */ public static void tartoFile(String sourceFile,String outputDir) throws IOException{ if(sourceFile.contains("../")){ throw new FileNotFoundException("文件不存在。。。"); } TarInputStream tarIn = null; // tar包的绝对路径 File file = new File(sourceFile); try{ tarIn = new TarInputStream(new GZIPInputStream(new BufferedInputStream( new FileInputStream(file))),1024 * 2); //创建输出目录 createDirectory(outputDir,null); TarEntry entry = null; while( (entry = tarIn.getNextEntry()) != null ){ if(entry.isDirectory()){//是目录 entry.getName(); //创建空目录 System.out.println("解压之后是目录"); createDirectory(outputDir,entry.getName()); }else{//是文件 File tmpFile = new File(outputDir + "/" + entry.getName()); createDirectory(tmpFile.getPath() + "/",null);//创建输出目录 OutputStream out = null; try{ out = new FileOutputStream(tmpFile); int length = 0; // 一次读取 2kb byte[] b = new byte[2048]; while((length = tarIn.read(b)) != -1){ out.write(b, 0, length); } }catch(IOException ex){ throw ex; }finally{ if(out!=null) out.close(); } } } }catch(IOException ex){ throw new IOException("解压归档文件出现异常",ex); } finally{ try{ if(tarIn != null){ tarIn.close(); } }catch(IOException ex){ throw new IOException("关闭tarFile出现异常",ex); } } } /** * 构建目录 * @param outputDir * @param subDir */ private static void createDirectory(String outputDir,String subDir){ File file = new File(outputDir); if(!(subDir == null || subDir.trim().equals(""))){//子目录不为空 file = new File(outputDir + "/" + subDir); } if(!file.exists()){ if(!file.getParentFile().exists()) file.getParentFile().mkdirs(); file.mkdirs(); } } //文件拷贝,目标文件存在时会拷贝失败 public static void copyFile(File file, File fileTo){ try { Files.copy(file.toPath(),fileTo.toPath()); } catch (IOException e) { log.info(e.getMessage()); } } /** * *

Method :copyDirectory *

Description : 复制文件夹 * 将源文件的外层目录也拷贝入新目录下 * @param sourcePathString * @param targetPathString */ public static void copyDirectory(String sourcePathString,String targetPathString){ if(!new File(sourcePathString).canRead()){ System.out.println("源文件夹" + sourcePathString + "不可读,无法复制!"); }else{ // yin 本地测试,上传记得更改为一个斜杠 String endDir = sourcePathString.split(File.separator)[sourcePathString.split(File.separator).length-1]; //将源文件的外层目录也拷贝入新目录下 targetPathString = targetPathString+File.separator+endDir; (new File(targetPathString)).mkdirs(); System.out.println("开始复制文件夹" + sourcePathString + "到" + targetPathString); File[] files = new File(sourcePathString).listFiles(); for (File file : files) { if (file.isFile()) { copyFileForce(new File(sourcePathString + File.separator + file.getName()), new File(targetPathString + File.separator + file.getName())); } else if (file.isDirectory()) { copyDirectory(sourcePathString + File.separator + file.getName(), targetPathString); } } System.out.println("复制文件夹" + sourcePathString + "到" + targetPathString + "结束"); } } //文件拷贝,强制覆盖目标文件 public static void copyFileForce(File file, File fileTo){ try { Files.copy(file.toPath(),fileTo.toPath(), StandardCopyOption.REPLACE_EXISTING.REPLACE_EXISTING); } catch (IOException e) { log.info(e.getMessage()); } } //解压.tar.gz文件 public static void unTarGz(String sourceFile,String outputDir) throws IOException{ TarInputStream tarIn = null; File file = new File(sourceFile); try{ tarIn = new TarInputStream(new GZIPInputStream( new BufferedInputStream(new FileInputStream(file))), 1024 * 2); createDirectory(outputDir,null);//创建输出目录 TarEntry entry = null; while( (entry = tarIn.getNextEntry()) != null ){ if(entry.isDirectory()){//是目录 entry.getName(); createDirectory(outputDir,entry.getName());//创建空目录 }else{//是文件 File tmpFile = new File(outputDir + "/" + entry.getName()); createDirectory(tmpFile.getParent() + "/",null);//创建输出目录 OutputStream out = null; try{ out = new FileOutputStream(tmpFile); int length = 0; byte[] b = new byte[2048]; while((length = tarIn.read(b)) != -1){ out.write(b, 0, length); } }catch(IOException ex){ throw ex; }finally{ if(out!=null) out.close(); } } } }catch(IOException ex){ throw new IOException("解压归档文件出现异常",ex); } finally{ try{ if(tarIn != null){ tarIn.close(); } }catch(IOException ex){ throw new IOException("关闭tarFile出现异常",ex); } } } }

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/9d776a3287.html