亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java實現(xiàn)多層級zip解壓的示例代碼

 更新時間:2024年12月23日 11:09:30   作者:鐵流是寶寶  
這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)多層級zip解壓的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考一下

前言

項目中偶然需要,希望能處理嵌套的壓縮包,但是又不希望把文件解壓處理。原本不希望重復(fù)造輪子,但沒有發(fā)現(xiàn)很好用的現(xiàn)成案例,就簡單處理了一下。

正文

java做zip解壓一般使用 ZipFile? 或者 ZipInputStream?。

在實際使用中,遇到了zip清單屬性無法讀取的報錯,最終采用了apache的ZipArchiveInputStream。主要是allowStoredEntriesWithDataDescriptor?屬性。

代碼完整使用的依賴如下:

	    <dependency>
	      <groupId>org.apache.commons</groupId>
	      <artifactId>commons-compress</artifactId>
	      <version>1.19</version>
	    </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.26</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>

代碼主要為符合業(yè)務(wù)需求而寫,比較簡陋。支持單次解壓和遞歸解壓,均通過回調(diào)返回緩沖流(無法關(guān)閉的緩沖流)。

必須要注意的是,一定不能提前關(guān)閉ZipArchiveInputStream,這個流一次會在getNextZipEntry后再次填充。

回調(diào)如果采用字節(jié)對內(nèi)存的壓力可能會比較大,所以通過緩沖流返回數(shù)據(jù)。為防止多人協(xié)作中出現(xiàn)誤關(guān)閉流,使用不關(guān)閉源流的緩沖流工具。

如果有需要解壓指定包,在入?yún)⒓右粋€filter就可以實現(xiàn)。

完整代碼實例

package xxx;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
用于輔助的不關(guān)閉原流的緩沖流
*/
public class NoCloseBufferStream extends BufferedInputStream {
public NoCloseBufferStream(InputStream in) {
super(in);
}
@Override
public void close() throws IOException {
//不實現(xiàn)任何東西就不會關(guān)閉原流
}
}
package xxx; //your package
 
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
 
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
 
/**
 * 注意:初始的輸入流是不會主動關(guān)閉的
 *
 * @author 鐵流
 */
@Slf4j
public class UnZipUtil {
 
    public static void main(String[] args) throws IOException {
 
        try (InputStream inputStream = Files.newInputStream(new File("/Users/tieliu/Desktop/test/aaaa.zip").toPath());) {
            loopUnzip(inputStream, (level, path, basePath, is) -> {
                is.close();
                log.info(" level: {},path: {},basePath: {}", level, path, basePath);
                return true;
            });
        }
    }
 
    /**
     * 遞歸解壓zip,只能解壓zip后綴名的壓縮文件
     *
     * @param inputStream  初始文件輸入流
     * @param loopCallBack 遞歸回調(diào),返回值控制是否向下遞歸
     * @throws IOException 文件流異常
     */
    public static void loopUnzip(InputStream inputStream, LoopCallBack loopCallBack) throws IOException {
        loopUnzip(inputStream, 0, "", loopCallBack);
    }
 
    private static void loopUnzip(InputStream inputStream, int level, String basePath, LoopCallBack loopCallBack) throws IOException {
        decompress(inputStream, (path, is) -> {
            // 此處決定是否繼續(xù)向下
            if (loopCallBack.call(level, path, basePath, is) && path.endsWith(".zip")) {
                loopUnzip(is, level + 1, basePath + "/" + path, loopCallBack);
            }
        });
    }
 
    /**
     * 解壓zip,必須是zip結(jié)尾的文件(錯誤屬性的文件會被排除,因為不排除java也解壓不了)
     *
     * @param inputStream 初始輸入流
     * @param callBack    回調(diào)
     * @throws IOException io異常
     */
    public static void decompress(InputStream inputStream, CallBack callBack) throws IOException {
        try (NoCloseBufferStream bufferedInputStream = new NoCloseBufferStream(inputStream);
             ZipArchiveInputStream zipInputStream = new ZipArchiveInputStream(bufferedInputStream, CharsetUtil.defaultCharset().name(), true, true)) {
            decompress(zipInputStream, callBack);
        }
    }
 
    public static void decompress(byte[] bytes, CallBack callBack) throws IOException {
        try (ByteArrayInputStream inputStream = IoUtil.toStream(bytes);) {
            bytes = null;
            decompress(inputStream, callBack);
        }
    }
 
    private static void decompress(ZipArchiveInputStream inputStream, CallBack callBack) throws IOException {
        ZipArchiveEntry nextEntry = inputStream.getNextZipEntry();
        while (nextEntry != null) {
            final String name = nextEntry.getName();
            //過濾無用文件
            if (!name.startsWith("__MACOSX") && !name.contains(".DS_Store") && !name.contains("Thumbs.db") && !name.startsWith("._")) {
                if (!nextEntry.isDirectory()) {
                    callBack.call(name, new NoCloseBufferStream(inputStream));
                }
            }
            nextEntry = inputStream.getNextZipEntry();
        }
    }
 
    @FunctionalInterface
    public static interface CallBack {
        void call(String relativePath, InputStream is) throws IOException;
    }
 
    @FunctionalInterface
    public static interface LoopCallBack {
        boolean call(int level, String relativePath, String basePath, InputStream is) throws IOException;
    }
 
}

到此這篇關(guān)于java實現(xiàn)多層級zip解壓的示例代碼的文章就介紹到這了,更多相關(guān)java zip解壓內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring整合quartz做定時任務(wù)的示例代碼

    Spring整合quartz做定時任務(wù)的示例代碼

    這篇文章主要介紹了在spring項目使用quartz做定時任務(wù),首先我這里的項目已經(jīng)是一個可以跑起來的完整項目,web.xml里面的配置我就不貼出來了,具體實例代碼跟隨小編一起看看吧
    2022-01-01
  • Java字段Stream排序常用方式

    Java字段Stream排序常用方式

    這篇文章主要給大家介紹了關(guān)于Java字段Stream排序常用方式的相關(guān)資料,我們在處理數(shù)據(jù)的時候經(jīng)常會需要進行排序后再返回給前端調(diào)用,比如按照時間升序排序,前端展示數(shù)據(jù)就是按時間先后進行排序,需要的朋友可以參考下
    2023-09-09
  • JAVAEE中用Session簡單實現(xiàn)購物車功能示例代碼

    JAVAEE中用Session簡單實現(xiàn)購物車功能示例代碼

    本篇文章主要介紹了JAVAEE中用Session簡單實現(xiàn)購物車功能示例代碼,非常具有實用價值,需要的朋友可以參考下。
    2017-03-03
  • Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例

    Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例

    本篇文章主要介紹了Spring配置多個數(shù)據(jù)源并實現(xiàn)動態(tài)切換示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • java生成圖片驗證碼示例程序

    java生成圖片驗證碼示例程序

    這篇文章主要介紹了java生成圖片驗證碼示例程序,大家參考使用吧
    2013-11-11
  • SpringCloud網(wǎng)關(guān)組件zuul實例解析

    SpringCloud網(wǎng)關(guān)組件zuul實例解析

    這篇文章主要介紹了SpringCloud網(wǎng)關(guān)組件zuul實例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • Java中Calendar日歷類型常見方法詳解

    Java中Calendar日歷類型常見方法詳解

    Calendar是Java中常用的時間處理工具之一,它提供了很多日歷類型常見方法,下面是一些常用的方法及對應(yīng)的代碼和運行結(jié)果,感興趣的朋友一起看看吧
    2023-11-11
  • SpringBoot隨機數(shù)設(shè)置及參數(shù)間引用的操作步驟

    SpringBoot隨機數(shù)設(shè)置及參數(shù)間引用的操作步驟

    在Spring Boot配置文件中設(shè)置屬性時,除了可以像前面示例中顯示的配置屬性值外,還可以使用隨機值和參數(shù)間引用對屬性值進行設(shè)置。下面給大家介紹SpringBoot參數(shù)間引用隨機數(shù)設(shè)置的操作步驟,感興趣的朋友一起看看吧
    2021-06-06
  • 使用Java實現(xiàn)Excel轉(zhuǎn)PDF的示例詳解

    使用Java實現(xiàn)Excel轉(zhuǎn)PDF的示例詳解

    在實際的開發(fā)過程中,我們常常會遇到需要將 Excel 文件轉(zhuǎn)換為 PDF 文件的需求,本文為大家介紹一種Java中的常見實現(xiàn)方式,需要的可以參考一下
    2025-02-02
  • Mybatis的parameterType造成線程阻塞問題分析

    Mybatis的parameterType造成線程阻塞問題分析

    這篇文章主要詳細(xì)分析了Mybatis的parameterType造成線程阻塞問題,文中有詳細(xì)的解決方法,及相關(guān)的代碼示例,具有一定的參考價值,感興趣的朋友可以借鑒閱讀
    2023-06-06

最新評論