Java &引用;ZipException-读取short buff时文件意外结束;将Zip内容读入字符串时

Java &引用;ZipException-读取short buff时文件意外结束;将Zip内容读入字符串时,java,apache-camel,ibm-mq,zipfile,zip4j,Java,Apache Camel,Ibm Mq,Zipfile,Zip4j,我正在使用zip4j库来压缩和解压文件(xml)。对于传入的字符串,我需要将字符串的内容写入一个xml文件,然后将该文件压缩成一个zip文件,然后再将压缩文件的字节[]内容传输到apache camelbody对象中。拉链部分工作正常,这里没有问题 当我试图将消息读回我的应用程序时,出现以下错误- net.lingala.zip4j.exception.ZipException: unexpected end of file when reading short buff at net.

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

当我试图将消息读回我的应用程序时,出现以下错误-

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)
我所做的基本上是-

  • 使用`exchange.getIn().getBody(byte[].class)方法从
    exchange
    对象获取
    byte[]
    数组
  • 字节[]
    写入文件
  • 由于这是一个zip负载,我将该文件重命名为
    .zip
    文件
  • 然后,我尝试将zip文件的内容读入
    字符串中
  • 这是密码-

    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;
        }
    
    知道发生了什么吗?
    顺便说一句,我正在一个Unix设备中尝试这些功能。

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


    据你所知,文本末尾的一个离群的
    ~
    字符破坏了它。

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


    据您所知,文本末尾的一个零散的
    ~
    字符破坏了它。

    看起来您正在使用Zip4j的v1.x。请尝试升级到最新版本(2.1.2)。由于使用v2.x时api发生了更改,您必须对代码进行一些小的更改。好处是,使用v2.x,您不必创建文件来读回内容。您可以使用
    ByteArrayOutputStream
    并将字节数组传入该流,然后将
    ByteArrayOutputStream
    传入
    ZipInputStream
    。请查看Zip4j自述文件中的流部分,以查看更详细的示例。如果您在2.x中仍然面临此问题,请告诉我。另外,请确保传入的字节数组与返回的字节数组内容相同。用一个小文件试试这个,这样你就可以打印和比较字节数组了。是的,你说得对-我使用的是
    1.3.2
    version。如果下游系统也使用
    zip4j
    1.3.2
    ,是否会出现问题?我认为它将向后兼容,但仍然..升级之前,您可以做的第一件事是检查字节数组内容。最有可能的情况是,您没有取回保存的完整字节数组内容。这些文件在以后的处理过程中是必需的,因此我认为BAS不会添加太多内容。这是平台问题吗?我的意思是,我能够在本地的Windows环境中正确地阅读它,但不知何故,它在Unix环境中失败了。还值得注意的是,unix中local中的内容并不相同,尽管两者都使用
    zip4j
    进行压缩和解压缩。看起来您使用的是zip4j的v1.x。请尝试升级到最新版本(2.1.2)。由于使用v2.x时api发生了更改,您必须对代码进行一些小的更改。好处是,使用v2.x,您不必创建文件来读回内容。您可以使用
    ByteArrayOutputStream
    并将字节数组传入该流,然后将
    ByteArrayOutputStream
    传入
    ZipInputStream
    。请查看Zip4j自述文件中的流部分,以查看更详细的示例。如果您在2.x中仍然面临此问题,请告诉我。另外,请确保传入的字节数组与返回的字节数组内容相同。用一个小文件试试这个,这样你就可以打印和比较字节数组了。是的,你说得对-我使用的是
    1.3.2
    version。如果下游系统也使用
    zip4j
    1.3.2
    ,是否会出现问题?我认为它将向后兼容,但仍然..升级之前,您可以做的第一件事是检查字节数组内容。最有可能的情况是,您没有取回保存的完整字节数组内容。这些文件在以后的处理过程中是必需的,因此我认为BAS不会添加太多内容。这是平台问题吗?我的意思是,我能够在本地的Windows环境中正确地阅读它,但不知何故,它在Unix环境中失败了。可能还值得注意的是,unix中local中的内容并不相同,尽管两者都使用
    zip4j
    进行压缩和解压缩。
    String
    不是二进制数据的容器。同意,但以前遗留代码执行过其他操作(没有二进制数据,只是普通的
    String
    )。我们需要把它们清除掉。这段代码没有任何异常处理,这一事实使情况变得更糟。和平
    String
    不是二进制数据的容器。同意,但以前有其他操作是由遗留代码执行的(它没有二进制数据,只是普通的旧
    String
    )。我们需要把它们清除掉。这段代码没有任何异常处理,这一事实使情况变得更糟。和平!
    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)