You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用commons-compress判断InputStream形式的7Z压缩包是否受密码保护

7z文件加密检测实现方案(仅持有InputStream场景)

实现原理

7z格式解析需要随机访问内容,无法直接适配单向读取的普通InputStream,因此先将输入流全量读取为字节数组,封装为 Commons Compress 提供的SeekableInMemoryByteChannel(支持随机访问的内存通道),即可复用原有基于异常的加密判定逻辑。

示例代码

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;
import java.io.IOException;
import java.io.InputStream;

public class SevenZEncryptCheckUtil {

    public static boolean check7zEncrypted(InputStream sevenzInputStream) throws IOException {
        // 1. 将输入流全量读取为字节数组
        byte[] sevenzContent = sevenzInputStream.readAllBytes();

        // 2. 构造内存随机访问通道,自动关闭资源
        try (SeekableInMemoryByteChannel memoryChannel = new SeekableInMemoryByteChannel(sevenzContent);
             SevenZFile sevenZFile = new SevenZFile(memoryChannel)) {

            SevenZArchiveEntry entry = sevenZFile.getNextEntry();
            // 空压缩包直接返回未加密
            if (entry == null) {
                return false;
            }
            // 尝试读取内容触发解密校验
            sevenZFile.read();
            // 无加密相关异常抛出则视为未加密
            return false;
        } catch (IOException e) {
            // 匹配无密码访问加密文件的特定异常信息
            String errMsg = e.getMessage();
            return errMsg != null && errMsg.contains("Cannot read encrypted files without a password");
        }
    }
}

注意事项

  • JDK 9及以上才支持InputStream.readAllBytes(),低版本JDK可以替换为org.apache.commons.io.IOUtils.toByteArray(sevenzInputStream)(需引入commons-io依赖)自行实现流到字节数组的转换。
  • 若待检测的7z文件体积很大,全量读取到内存会产生较高的堆内存占用,这种场景建议先将InputStream写入本地临时文件,再用原有本地文件逻辑检测,避免OOM问题。
  • 异常判断逻辑需匹配特定错误信息,避免将文件损坏、流读取失败等其他IO异常误判为加密状态。

内容的提问来源于stack exchange,提问作者user3629

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:48:03