【发布时间】:2026-01-01 09:45:02
【问题描述】:
我正在使用zip4j 库来压缩和解压缩文件(尤其是xml)。对于传入的String,我需要将String 的内容写入xml 文件,然后将该文件压缩到一个zip 文件中,然后再将zip 文件的byte[] 内容传输到@ 987654327@ 身体对象。压缩部分工作正常,这里没有问题。
当我尝试将消息读回我的应用程序时,我收到以下错误 -
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[]数组 - 将
byte[]写入文件 - 由于这是一个 zip 有效负载,我将文件重命名为
.zip文件 - 然后我尝试将 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 盒子里尝试这些。
【问题讨论】:
-
看起来您使用的是 Zip4j 的 v1.x。请尝试升级到最新版本 (2.1.2)。由于 api 已随 v2.x 更改,您将不得不做一些小的代码更改。好处是使用 v2.x,您不必创建文件来读取内容。您可以使用
ByteArrayOutputStream并将您的字节数组传递到该流中,然后将ByteArrayOutputStream传递给ZipInputStream。请查看 Zip4j 自述文件中的流部分以查看更详细的示例。如果您在 2.x 中仍然遇到这个问题,请告诉我。 -
另外,请确保您传入的字节数组与您返回的字节数组的内容相同。用一个小文件试试这个,这样你就可以打印和比较字节数组了。
-
是的,你是对的 - 我使用的是
1.3.2版本。如果下游系统也使用1.3.2或zip4j会不会有问题?我假设它会向后兼容,但仍然.. -
也许在升级之前你可以做的第一件事就是检查字节数组的内容。很可能您没有取回您保留的完整字节数组内容。
-
这些文件是以后一些处理目的所必需的,所以我认为baos不会添加太多。这是平台问题吗?我的意思是,我可以在本地 Windows 环境中正确读取它,但在 Unix 机器中它以某种方式失败。可能还值得注意的是,unix 中 local 的内容并不相同,尽管两者都使用
zip4j进行压缩和解压缩。
标签: java apache-camel ibm-mq zipfile zip4j