在Java中如何实现Gzip的完整性校验(类似gzip -t <file> 命令)?

在Java中如何实现Gzip的完整性校验(类似gzip -t <file> 命令)?

已解决:

GZIPInputStream+FileOutputStream会自己检查是否完整,不完整会直接抛ZipException

    /**
     * 解压GZIP
     *
     * @param input
     * @param output
     * @throws IOException
     */
    public static void decompressGzip(File input, File output) throws IOException, ZipException {
        try (GZIPInputStream in = new GZIPInputStream(new FileInputStream(input))) {
            try (FileOutputStream out = new FileOutputStream(output)) {
                byte[] buffer = new byte[1024];
                int len;
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
            }
        }
    }
阅读 2.7k
2 个回答

gzip,zip, rar这一类的test命令的算法似乎是解压缩到/dev/null,判断是否有错误来决定的,由于不直接写入磁盘IO,所以速度极快。所以如果你要实现它的算法你也可以这么干。

Java 中使用null设备的输出流为OutputStream.nullOutputStream() (Java >= 11),所以你将gzip数据流输出到这个流中,检查是否抛出异常就行了

可以试一下:

import java.util.zip.GZIPInputStream;
import java.util.zip.CRC32;

public class GzipChecksumValidator {
    public static boolean isValid(String gzipFilePath) throws Exception {
        byte[] buffer = new byte[1024];
        int count;
        long crc = 0; // 存储 CRC 值
        byte[] crcBytes = new byte[8]; // 存储 Gzip 文件头部中的 CRC 值

        try (GZIPInputStream gzipStream = new GZIPInputStream(new FileInputStream(gzipFilePath))) {
            while ((count = gzipStream.read(buffer)) != -1) {
                crc = new CRC32().getValue();
                crc.update(buffer, 0, count); // 更新 CRC 值
            }

            InputStream input = new FileInputStream(gzipFilePath);
            long skip = input.skip(8);
            if (skip != 8) {
                throw new IOException("Invalid Gzip File Format!");
            }
            int bytesRead = input.read(crcBytes);
            if (bytesRead != -1) {
                throw new IOException("Failed to read CRC32 from Gzip file header");
            }

            long crcFromHeader = new BigInteger(crcBytes).longValue(); // 从 Gzip 文件头部获取 CRC 值

            return crc == crcFromHeader;
        }
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题