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

BZip2Compressor无法完整解压XML文件,解析报错求助

BZ2解压后XML文件不完整的解决方案

你遇到的XML解析报错(XML document structures must start and end within the same entity),本质是解压后的文件被截断,核心原因是IO流未正确关闭导致缓冲区数据未完全写入磁盘,另外代码里还有几个潜在问题需要修复:

1. 核心问题:输出流未关闭,缓冲区数据残留

你的extractData方法中,BufferedOutputStream会把数据暂存到缓冲区,只有调用flush()或close()时才会将所有数据写入磁盘。原代码没有关闭输出流,导致最后一批缓冲区数据无法写入,直接造成文件截断。

2. 其他需要修复的潜在问题

  • 目录创建用mkdir():如果目标目录的父路径不存在,mkdir()会创建失败,应该改用mkdirs()递归创建所有层级的目录。
  • 硬编码路径分隔符:直接用/拼接路径在Windows系统会出错,建议用Paths API或File.separator处理路径拼接。
  • 流资源泄漏:所有IO流都需要正确关闭,推荐用Java 7+的try-with-resources语法,自动管理流的关闭,避免资源泄漏。

修正后的完整代码

import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;

public class Bz2Decompressor {
    private static String defaultUnzipDirPath = "/Users/name/Desktop/UnzipFiles";
    private static final int BUFFER_SIZE = 8192 * 32;

    public static void main(String[] args) {
        decompress("/Users/name/Desktop/Resources/myFile.xml.bz2", defaultUnzipDirPath);
    }

    public static void decompress(String bz2File, String unzipFileDirPath) {
        File resultDir = new File(unzipFileDirPath);
        // 递归创建目录,确保父目录不存在也能成功创建
        if (!resultDir.exists()) {
            resultDir.mkdirs();
        }

        // 使用try-with-resources自动关闭所有流,无需手动调用close()
        try (FileInputStream fis = new FileInputStream(bz2File);
             BZip2CompressorInputStream bzIn = new BZip2CompressorInputStream(fis, true);
             BufferedOutputStream bos = new BufferedOutputStream(
                     new FileOutputStream(Paths.get(unzipFileDirPath, "output.xml").toFile()))) {

            extractData(bzIn, bos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void extractData(BZip2CompressorInputStream bzIn, BufferedOutputStream bos) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        int read;
        while ((read = bzIn.read(buffer)) != -1) {
            bos.write(buffer, 0, read);
        }
        // 显式刷新缓冲区,确保所有数据写入磁盘(try-with-resources关闭时也会自动刷新,双重保险)
        bos.flush();
    }
}

额外排查方向

如果修复后问题依旧,需要确认:

  • 原BZ2文件是否完整:用系统命令bzip2 -t myFile.xml.bz2校验文件完整性,如果命令报错,说明原文件已损坏,需要重新获取。
  • Apache Commons Compress版本:确保使用最新稳定版(如1.24.0),旧版本可能存在解压逻辑的bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:07:27