不同的ZipOutputStream结果在不同的平台上

时间:2012-06-08 15:00:56

标签: java servlets stream zip

我有生成zip输出流的代码,然后我通过servlet的响应流发送该流。在我的mac上进行开发测试时,一切正常,但是,当我将代码放在我的服务器(RHEL)上时,zip存档似乎已损坏。当我尝试使用jar列出文件的内容时,我得到:

java.util.zip.ZipException:打开zip文件时出错

但奇怪的是,用jar工程提取档案(但是其他unarchivers失败了)。

为了进一步测试,我确保zip文件的内容与我的mac和RHEL完全相同。在这两种情况下,zip文件的大小完全相同,但是,哈希(MD5)是不同的。

正如我所说,生成zip文件的代码和内容完全相同,所以我不知道发生了什么。我很确定我的zip文件创建是正确的,因为它正在其中一个平台上运行。在RHEL服务器上生成zip文件时没有任何问题。

思考?谢谢你的帮助。

编辑:这是代码......

// first add the kml document
ZipOutputStream stream = new ZipOutputStream(response.getOutputStream());
stream.putNextEntry(new ZipEntry("doc.kml"));
stream.write(kml.getBytes(), 0, kml.length());
stream.closeEntry();

File image = null;
byte[] bytes = null;
FileInputStream fstream = null;

// include the images for each type
File images = new File("/tmp/images");
String filename = null;

for(Type type: types) {
  filename = type.getName() + ".png";
  image = new File(images, filename);
  bytes = new byte[(int)image.length()];

  fstream = new FileInputStream(image);
  fstream.read(bytes);

  stream.putNextEntry(new ZipEntry(filename));
  stream.write(bytes);
  stream.closeEntry();

  fstream.close();
}

stream.finish();
stream.flush();
stream.close();

EDIT2:情节变粗,只要存档中只有一个图像,RHEL拉链流就好了。希望这足以让谷歌帮助我。

1 个答案:

答案 0 :(得分:2)

几个问题:

  • 不使用getBytes()将字符串转换为字节。这将使用平台字符集,在不同平台上可能会有所不同。始终使用显式字符集,例如getBytes("UTF-8")。此外,getBytes()的返回长度与String的长度无关。
  • 读取文件时,不要将它们完全读入内存(这不会缩放)。使用固定大小的byte []和while循环在InputStream和OutputStream之间进行复制。这个代码在网上有成千上万的例子。 (或使用公共场所IOUtils.copy
  • 之类的东西
  • 与上一点相关,InputStream.read()有一个返回值,不要忽略它。再次,您应该在任何示例中看到这一点,您会发现将InputStream复制到OutputStream的最佳方法。