Java解压压缩包(zip/rar/7z)

一、概述

主要实现解压压缩包,拿到压缩包中每个文件。

二、思路

针对压缩包的操作,首先需要拿到压缩包文件的流,然后利用第三方工具将流实例化,调用next方法迭代,然后分别操作压缩包中的单个文件。

三、代码实现

1.zip实现

jdk支持对zip流的操作,相关依赖在java.util.zip下

// 获取本地zip包
public void unzipByPath() {
    try {
        String localPath = "D:\\文件.zip";
        File file = new File(localPath);
        ZipInputStream zin; // 创建ZipInputStream对象
        InputStream inputStream = new FileInputStream(file);
        zin = new ZipInputStream(inputStream, Charset.forName("GBK")); // 实例化对象,指明要解压的文件
        ZipEntry entry;
        while ((entry = zin.getNextEntry()) != null) {
            System.out.println(zipEntry.getName());
            BufferedInputStream bs = new BufferedInputStream(zin);
            // 将文件信息写到byte数组中
            byte[] bytes = new byte[(int) entry.getSize()];
            bs.read(bytes, 0, (int) entry.getSize());
            if ("zip".equals(entry.getName().substring(entry.getName().lastIndexOf(".") + 1))) {
    			ZipInputStream secondZip = new ZipInputStream(new ByteArrayInputStream(bytes), Charset.forName("GBK"));
   				// 循环解压
			}
        }
        zin.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
// 获取远程zip包
public void unzipByUrl() {
    String fileUrl = "https://localhost:80/group1/M00/6D/A3/wKjScWE7PxqAQfUnAAGcIyZy0ZU422.zip";
    try {
        URL url = new URL(fileUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        int resultCode = conn.getResponseCode();
        if (200 == resultCode) {
            ZipInputStream zipInputStream = new ZipInputStream(conn.getInputStream(), Charset.forName("GBK"));
            ZipEntry zipEntry;
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                System.out.println(zipEntry.getName());
                BufferedInputStream bs = new BufferedInputStream(zipInputStream);
            	// 将文件信息写到byte数组中
                byte[] bytes = new byte[(int) zipEntry.getSize()];
                bs.read(bytes, 0, (int) zipEntry.getSize());
                if ("zip".equals(zipEntry.getName().substring(zipEntry.getName().lastIndexOf(".") + 1))) {
                    ZipInputStream secondZip = new ZipInputStream(new ByteArrayInputStream(bytes), Charset.forName("GBK"));
                    // 循环解压
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.rar实现

1)依赖



    com.github.junrar
    junrar
    4.0.0

2)代码

// 获取本地rar
public void unRarByPath() {
    String rarPath = "D:\\文件.rar";
    try {
        File outFileDir = new File(rarPath);
        Archive archive = new Archive(new FileInputStream(rarFile));
        FileHeader fileHeader;
         while ((fileHeader = archive.nextFileHeader()) != null) {
         	// 解决文件名中文乱码问题
             String fileName = fileHeader.getFileNameW().isEmpty() ? fileHeader.getFileNameString() :
                     fileHeader.getFileNameW();
             String fileExt =
                     fileName.substring(fileName.lastIndexOf(FileConstant.FILE_SEPARATOR) + 1);
             System.out.println(fileName);
             ByteArrayOutputStream os = new ByteArrayOutputStream();
             archive.extractFile(fileHeader, os);
            // 将文件信息写到byte数组中
             byte[] bytes = os.toByteArray();
             System.out.println(bytes.length);
             if ("rar".equals(fileExt)) {
                 Archive secondArchive = new Archive(new ByteArrayInputStream(bytes));
                 // 循环解压
             }
         }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// 获取远程rar
public void unRarByUrl() {
    String rarUrl = "https://localhost:80/group1/M00/6D/A3/wKjScWE7PxqAQfUnAAGcIyZy0ZU422.rar";
    try {
        URL url = new URL(rarUrl);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        int resultCode = conn.getResponseCode();
        if (200 == resultCode) {
            InputStream inputStream = conn.getInputStream();
            Archive archive = new Archive(inputStream);
            FileHeader fileHeader;
            while ((fileHeader = archive.nextFileHeader()) != null) {
            	// 解决文件名中文乱码问题
                String fileName = fileHeader.getFileNameW().isEmpty() ? fileHeader.getFileNameString() :
                        fileHeader.getFileNameW();
                String fileExt =
                        fileName.substring(fileName.lastIndexOf(FileConstant.FILE_SEPARATOR) + 1);
                System.out.println(fileName);
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                archive.extractFile(fileHeader, os);
            	// 将文件信息写到byte数组中
                byte[] bytes = os.toByteArray();
                System.out.println(bytes.length);
                if ("rar".equals(fileExt)) {
                    Archive secondArchive = new Archive(new ByteArrayInputStream(bytes));
                    // 循环解压
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3)注意
rar5的加密算法未开源,目前不支持对rar5的解压,建议压缩时选择rar4
Java解压压缩包(zip/rar/7z)_第1张图片

3.7z实现

由于7z的算法等原因,目前只有针对文件的解压,不能直接对流进行操作



   org.apache.commons
   commons-compress
   1.9



    org.tukaani
    xz
    1.5

// 解析本地7z文件
public void un7zByPath() {
    File srcFile = new File("C:\\文件.7z");//获取当前压缩文件
    //开始解压
    try {
        SevenZFile zIn = new SevenZFile(srcFile);
        SevenZArchiveEntry entry = null;
        File newFile = null;
        while ((entry = zIn.getNextEntry()) != null) {
            if (!entry.isDirectory()) {
                newFile = new File("destDirPath", entry.getName());
                if (!newFile.exists()) {
                    new File(newFile.getParent()).mkdirs();//创建此文件的上级目录
                }
                OutputStream out = new FileOutputStream(newFile);
                BufferedOutputStream bos = new BufferedOutputStream(out);
                int len = -1;
            	// 将文件信息写到byte数组中
                byte[] buf = new byte[(int) entry.getSize()];
                while ((len = zIn.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                }
                System.out.println(entry.getName() + "=" + Arrays.toString(buf));
                // 关流顺序,先打开的后关闭
                bos.close();
                out.close();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

实在不行可以考虑把远程文件写到磁盘再读成文件,不过这种方法不太靠谱,暂不考虑

四、总结

有关rar5不能解析,以及7z不能直接对流进行操作,后面找到解决方法再写

你可能感兴趣的:(日常记录,java)