文件解压专题-2:支持Gzip、Rar5、rar、7z、tar.gz、zip

文件解压专题:支持Gzip、Rar5、rar、7z、tar.gz、zip

Gzip解压

public class GzipUploadServiceImpl implements UploadService {
    @Override
    public boolean isOwn(FileType fileType) {
        return FileType.GZ == fileType;
    }

    @Override
    public void uploadFile(String targetPath, File file, int depth, boolean isReservedDir) throws IOException, RarException {
        if (file.getName().endsWith(TAR_GZ)) {
            new TarGzUploadServiceImpl().uploadFile(targetPath, file, depth, isReservedDir);
            return;
        }
        try (InputStream is = Files.newInputStream(file.toPath());
             GzipCompressorInputStream gzip = new GzipCompressorInputStream(is)) {
            // 获取文件名
            String fileName = gzip.getMetaData().getFilename();
            if (fileName == null) {
                String name = file.getName();
                fileName = name.substring(0, name.lastIndexOf(Constants.DOT));
                fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);
            }
            File destFile = FileUtils.getFile(targetPath, fileName);
            FileUtils.copyInputStreamToFile(gzip, destFile);
        } finally {
            new ProjectUtils().deleteTemFile(file);
        }
    }
}

Rar5解压

public class Rar5UploadServiceImpl implements UploadService {

    @Override
    public boolean isOwn(FileType fileType) {
        return FileType.RAR5 == fileType;
    }

    @Override
    public void uploadFile(String targetPath, File file, int count, boolean isReservedDir) throws IOException, RarException {
        ProjectUtils projectUtils = new ProjectUtils();
        if (count == Constants.MAX_DEPTH) {
            projectUtils.deleteTemFile(file);
            return;
        }

        //解压缩至指定目录outDir
        ExtractCallback.unrar5(file.getCanonicalPath(), targetPath, isReservedDir, count);

        projectUtils.deleteTemFile(file);
    }
}

具体实现Rar5的解压

import com.github.junrar.exception.RarException;

import net.sf.sevenzipjbinding.ExtractAskMode;
import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.IArchiveExtractCallback;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.ISequentialOutStream;
import net.sf.sevenzipjbinding.PropID;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;

public class ExtractCallback implements IArchiveExtractCallback {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExtractCallback.class);

    private IInArchive inArchive;
    private String ourDir;
    private boolean isReservedDir;
    private int depth;

    public ExtractCallback(IInArchive inArchive, String ourDir, boolean isReservedDir, int depth) {
        this.inArchive = inArchive;
        this.isReservedDir = isReservedDir;
        this.ourDir = ourDir;
        this.depth = depth;
    }

    @Override
    public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
        String path = (String) inArchive.getProperty(index, PropID.PATH);
        if (!isReservedDir) {
            path = path.substring(path.lastIndexOf(File.separator) + 1);
        }
        final boolean isFolder = (boolean) inArchive.getProperty(index, PropID.IS_FOLDER);
        final String[] oldPath = {""};
        String finalPath = path;
        return data -> {
            try {
                if (!isFolder) {
                    String newPath = ourDir + File.separator + finalPath;
                    File file = new File(newPath);
                    if (finalPath.equals(oldPath[0])){
                        save2File(file, data,true);
                    } else {
                        save2File(file, data,false);
                    }
                    String targetPath = newPath.substring(0, newPath.lastIndexOf(File.separator));
                    new FileUpDownService().delUploadFile(targetPath, file, depth, isReservedDir);
                    oldPath[0] = finalPath;
                }
            } catch (IOException | RarException e) {
                LOGGER.error(e.getMessage(), e);
            }
            return data.length;
        };
    }

    @Override
    public void prepareOperation(ExtractAskMode extractAskMode) throws SevenZipException {

    }

    @Override
    public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {

    }

    public boolean save2File(File file, byte[] msg, boolean append) {
        OutputStream fos = null;
        try {
            File parent = file.getParentFile();
            if ((!parent.exists()) && (!parent.mkdirs())) {
                return false;
            }
            fos = new FileOutputStream(file, append);
            fos.write(msg);
            fos.flush();
            return true;
        } catch (IOException e) {
            return false;
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
        }
    }

    public static void unrar5(String rarDir, String outDir, boolean isReservedDir, int depth) {
        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 第一个参数是需要解压的压缩包路径,第二个参数参考JdkAPI文档的RandomAccessFile
            randomAccessFile = new RandomAccessFile(rarDir, "r");
            inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));

            int[] in = new int[inArchive.getNumberOfItems()];
            for (int i = 0; i < in.length; i++) {
                in[i] = i;
            }
            inArchive.extract(in, true, new ExtractCallback(inArchive, outDir, isReservedDir, depth));
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            try {
                inArchive.close();
                randomAccessFile.close();
            } catch (IOException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }

    @Override
    public void setTotal(long l) throws SevenZipException {
    }

    @Override
    public void setCompleted(long l) throws SevenZipException {
    }
}

7z解压

public class SevenZUploadServiceImpl implements UploadService {
    @Override
    public boolean isOwn(FileType fileType) {
        return FileType.SEVEN_Z == fileType;
    }

    @Override
    public void uploadFile(String targetPath, File file, int count, boolean isReservedDir) throws IOException, RarException {
        ProjectUtils projectUtils = new ProjectUtils();
        if (count == Constants.MAX_DEPTH) {
            projectUtils.deleteTemFile(file);
            return;
        }
        int depth = count;
        depth++;
        SevenZFile sevenZFile = new SevenZFile(file);
        SevenZArchiveEntry entry;
        String fileName;
        int len;
        byte[] buf = new byte[4096];
        String newPath = targetPath;
        while ((entry = sevenZFile.getNextEntry()) != null) {
            if (entry.isDirectory()) {
                if (isReservedDir) {
                    newPath = FileUtils.getFile(targetPath, entry.getName()).getCanonicalPath();
                    FileUtil.createPathIfNotExist(newPath);
                }
                continue;
            }
            String tarName = entry.getName();
            fileName = isReservedDir ? tarName : tarName.substring(tarName.lastIndexOf(Constants.UNIX_SEPARATOR) + 1);
            // 重名嵌套压缩包必须重命名
            if (file.getName().endsWith(fileName)) {
                fileName = projectUtils.getTimestamp() + Constants.UNDERLINE + fileName;
            }
            File destFile = FileUtils.getFile(targetPath, fileName);
            try (OutputStream fos = Files.newOutputStream(destFile.toPath())) {
                while ((len = sevenZFile.read(buf, 0, buf.length)) != -1) {
                    fos.write(buf, 0, len);
                }
            }
            new FileUpDownService().delUploadFile(newPath, destFile, depth, isReservedDir);
        }
        sevenZFile.close();
        projectUtils.deleteTemFile(file);
    }
}

tar.gz解压

public class TarGzUploadServiceImpl implements UploadService {

    @Override
    public boolean isOwn(FileType fileType) {
        return FileType.TAR_GZ == fileType;
    }

    @Override
    public void uploadFile(String targetPath, File file, int count, boolean isReservedDir) throws IOException, RarException {
        ProjectUtils projectUtils = new ProjectUtils();
        if (count == Constants.MAX_DEPTH) {
            projectUtils.deleteTemFile(file);
            return;
        }
        int depth = count;
        depth++;
        String name = file.getName();
        if (!name.endsWith(TAR_GZ) && name.endsWith(GZ)) {
            new GzipUploadServiceImpl().uploadFile(targetPath, file, count, isReservedDir);
            return;
        }
        try (InputStream is = Files.newInputStream(file.toPath());
             TarInputStream tarIn = new TarInputStream(new GZIPInputStream(is))) {
            TarEntry tarEntry;
            String fileName;
            String newPath = targetPath;
            while ((tarEntry = tarIn.getNextEntry()) != null) {
                if (tarEntry.isDirectory()) {
                    if (isReservedDir) {
                        newPath = FileUtils.getFile(targetPath, tarEntry.getName()).getCanonicalPath();
                        FileUtil.createPathIfNotExist(newPath);
                    }
                    continue;
                }
                String tarName = tarEntry.getName();
                fileName = isReservedDir ? tarName : tarName.substring(tarName.lastIndexOf(Constants.UNIX_SEPARATOR) + 1);
                // 重名嵌套压缩包必须重命名
                if (name.endsWith(fileName)) {
                    fileName = projectUtils.getTimestamp() + Constants.UNDERLINE + fileName;
                }
                File destFile = FileUtils.getFile(targetPath, fileName);
                try (FileOutputStream fos = new FileOutputStream(destFile)) {
                    IOUtils.copy(tarIn, fos);
                }
                new FileUpDownService().delUploadFile(newPath, destFile, depth, isReservedDir);
            }
        } finally {
            projectUtils.deleteTemFile(file);
        }
    }
}

zip解压

public class ZipUploadServiceImpl implements UploadService {

    @Override
    public boolean isOwn(FileType fileType) {
        return FileType.ZIP == fileType;
    }

    @Override
    public void uploadFile(String targetPath, File file, int count, boolean isReservedDir)  throws IOException, RarException {
        ProjectUtils projectUtils = new ProjectUtils();
        if (count == Constants.MAX_DEPTH) {
            projectUtils.deleteTemFile(file);
            return;
        }
        int depth = count;
        depth++;
        try (InputStream is = Files.newInputStream(file.toPath());
             ZipArchiveInputStream zip = new ZipArchiveInputStream(is, ENCODING_GBK)) {
            ZipArchiveEntry zipEntry;
            String fileName;
            String newPath = targetPath;
            while ((zipEntry = zip.getNextZipEntry()) != null) {
                if (zipEntry.isDirectory()) {
                    if (isReservedDir) {
                        newPath = FileUtils.getFile(targetPath, zipEntry.getName()).getCanonicalPath();
                        FileUtil.createPathIfNotExist(newPath);
                    }
                    continue;
                }
                String tarName = zipEntry.getName();
                fileName = isReservedDir ? tarName : tarName.substring(tarName.lastIndexOf(Constants.UNIX_SEPARATOR) + 1);
                // 重名嵌套压缩包必须重命名
                if (file.getName().endsWith(fileName)) {
                    fileName = projectUtils.getTimestamp() + Constants.UNDERLINE + fileName;
                }
                File destFile = FileUtils.getFile(targetPath, fileName);
                try (FileOutputStream fos = new FileOutputStream(destFile)) {
                    IOUtils.copy(zip, fos);
                }
                new FileUpDownService().delUploadFile(newPath, destFile, depth, isReservedDir);
            }
        }
        finally {
            projectUtils.deleteTemFile(file);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值