首页 > 解决方案 > 将 Zip 内容读入字符串时出现“ZipException - 读取短缓冲区时文件意外结束”

问题描述

我正在使用该zip4j库来压缩和解压缩文件(xml特别是)。对于传入的String,我需要将 的内容写入String文件xml,然后将该文件压缩到 zip 文件中,然后再将 zip 文件的byte[]内容传输到apache camel正文对象中。拉链部分工作正常,这里没有问题。

当我尝试将消息读回我的应用程序时,我收到以下错误 -

net.lingala.zip4j.exception.ZipException: unexpected end of file when reading short buff
    at net.lingala.zip4j.core.HeaderReader.readIntoBuff(HeaderReader.java:1094)
    at net.lingala.zip4j.core.HeaderReader.readCentralDirectory(HeaderReader.java:221)
    at net.lingala.zip4j.core.HeaderReader.readAllHeaders(HeaderReader.java:94)
    at net.lingala.zip4j.core.ZipFile.readZipInfo(ZipFile.java:425)
    at net.lingala.zip4j.core.ZipFile.getFileHeaders(ZipFile.java:688)
    at ZipUtil.unzipFile(ZipUtil.java:230)
    at ZipUtil.unzipFile(ZipUtil.java:218)

我所做的基本上是-

  1. 使用 `exchange.getIn().getBody(byte[].class) 方法从对象中获取byte[]数组exchange
  2. 写入byte[]文件
  3. 由于这是一个 zip 有效负载,我将文件重命名为一个.zip文件
  4. 然后我尝试将 zip 文件的内容读入String.

这是代码 -

public String extractMessageFromExchange(Exchange exchange) {
 byte[] bytes = exchange.getIn().getBody(byte[].class);
 File file = null;
 File zipFile = null;

 /*
 * 1. Dump bytes into a file
 * 2. Add ".zip" extension to file
 * Now, Unzip the file (It's convoluted, but that's how we receive payload back from downstream)
 * 3. Use ZipUtil to get path to the unzipped file
 * 4. Use FileUtil to read the contents of the file into a String object
 */

 try {
        String filePath = zipFileGenPath + zipFileGenSuffix + hyphen + 
 incoming;
        file = new File(filePath);
        FileUtils.writeByteArrayToFile(file, bytes);
        zipFile = new File(filePath+zipFileGenExt);
        boolean renamed = file.renameTo(zipFile);
        log.info("Temp zip file created at - " + zipFile.getPath());
                     String underlyingXMLFilePath = 
 unzipFile(zipFile.getPath(), zipFileGenPath); //gives the path
        incomingMessage = FileUtils.readFileToString(new 
 File(underlyingXMLFilePath));
         return incomingMessage;
     } catch (Exception e) {
         log.error("Exception occurred while reading byte[] payload into zip 
 file : ", e.getMessage());
         log.error("Error stacktrace: ", e);
     } finally {
         deleteFile(zipFile);
 }
}

然后是罪魁祸首代码 -

public String unzipFile(final String sourceZipFile, String updateToDir) throws Exception {
        ZipFile zipFile = new ZipFile(sourceZipFile);
        return unzipFile(zipFile, updateToDir);
    }

    public String unzipFile(ZipFile zipFile, String updateToDir) throws Exception {
        ZipInputStream is = null;
        OutputStream os = null;
        ZipParameters parameters = new ZipParameters();
        parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
        parameters.setEncryptFiles(false);

        try {
            List fileHeaderList = zipFile.getFileHeaders();
            for (int i = 0; i < fileHeaderList.size(); i++) {
                FileHeader fileHeader = (FileHeader) fileHeaderList.get(i);
                if (fileHeader != null) {
                    String outFilePath = updateToDir + File.separator + fileHeader.getFileName();
                    File outFile = new File(outFilePath);
                    is = zipFile.getInputStream(fileHeader);
                    os = new FileOutputStream(outFile);
                    int readLen = -1;
                    byte[] buff = new byte[4096];
                    while ((readLen = is.read(buff)) != -1) {
                        os.write(buff, 0, readLen);
                    }
                    return outFilePath;
                }
            }
        } finally {
            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(os);
        }
        return null;
    }

结果->

ZipUtil - Exception occurred while reading byte[] payload into zip file : 
ZipUtil - Error stacktrace: 
net.lingala.zip4j.exception.ZipException: unexpected end of file when reading short buff
    at net.lingala.zip4j.core.HeaderReader.readIntoBuff(HeaderReader.java:1094)
    at net.lingala.zip4j.core.HeaderReader.readCentralDirectory(HeaderReader.java:221)
    at net.lingala.zip4j.core.HeaderReader.readAllHeaders(HeaderReader.java:94)
    at net.lingala.zip4j.core.ZipFile.readZipInfo(ZipFile.java:425)
    at net.lingala.zip4j.core.ZipFile.getFileHeaders(ZipFile.java:688)
    at ZipUtil.unzipFile(ZipUtil.java:230)
    at ZipUtil.unzipFile(ZipUtil.java:218)
    at ZipUtil.extractMessageFromExchange(ZipUtil.java:96)

知道发生了什么吗?PS。我正在一个 Unix 盒子里尝试这些。

标签: javaapache-camelibm-mqzipfilezip4j

解决方案


我设法解决了它。问题不在于压缩逻辑或zip4j,而在于解压缩开始之前的一个顽皮的小“convertBodyToString”方法。这实质上导致了原始压缩消息的损坏,因此解压缩无法成功。

众所周知,~文本末尾的一个杂散字符破坏了它。


推荐阅读