我正在编写一个Java小程序,需要读取ZIP文件中的一些XML和图像文件。 Zip文件将通过HTTP下载,applet是无符号的,因此我需要使用java.util.zip.ZipInputStream
来操纵数据。当我尝试在Zip文件中读取PNG文件时出现问题。
我处理Zip文件的步骤:
通过Http
下载ZipURL resourceURL = new URL(source);
HttpURLConnection httpConnection= (HttpURLConnection) resourceURL.openConnection();
httpConnection.connect();
InputStream resourceFileIn = httpConnection.getInputStream();
使用ZipInputStream保存下载的数据
ZipInputStream resourceZipIn = new ZipInputStream(resourceFileIn);
遍历每个ZipEntry并提取相应的字节数组
ArrayList<ExtractedEntry> extractedList = new ArrayList<ExtractedEntry>();
ZipEntry currentEntry;
while ((currentEntry = resourceZipIn.getNextEntry()) != null) {
byte[] byteHolder = new byte[(int) currentEntry.getSize()];
resourceZipIn.read(byteHolder, 0, byteHolder.length);
extractedList.add(new ExtractedEntry(currentEntry.getName(), byteHolder));
}
备注:提取的每个ZipEntry都由以下类保存
public class ExtractedEntry {
private String name;
private byte[] byteArray;
public ExtractedEntry(String name, byte[] byteArray) {
super();
this.name = name;
this.byteArray = byteArray;
}
public String getName() {
return name;
}
public byte[] getByteArray() {
return byteArray;
}
}
在解压缩列表中找到我想要读取的文件
ExtractedEntry bgEntry = null;
for (int j = 0; j < extractedList.size() && bgEntry == null; j++) {
if (extractedList.get(j).getName().equals("background.png")) {
bgEntry = extractedList.get(j);
}
}
根据需要执行特定操作
InputStream mapBgIn = new ByteArrayInputStream(bgEntry.getByteArray());
BufferedImage bgEntry = ImageIO.read(bgIn);
我只列出了读取PNG文件的操作,因为这是我遇到问题的地方。当我尝试以上述方式读取图像时,我总是在第5步的最后一行收到以下错误。
javax.imageio.IIOException: Error reading PNG image data at com.sun.imageio.plugins.png.PNGImageReader.readImage(Unknown Source)
at com.sun.imageio.plugins.png.PNGImageReader.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at com.quadd.soft.game.wtd.lib.resource.ResourceManager.loadHttpZipRes(ResourceManager.java:685)
Caused by: javax.imageio.IIOException: Unknown row filter type (= 7)!
at com.sun.imageio.plugins.png.PNGImageReader.decodePass(Unknown Source)
at com.sun.imageio.plugins.png.PNGImageReader.decodeImage(Unknown Source)
... 29 more
但是,如果我从步骤3开始以下列方式阅读图像,则没有问题。
ZipInputStream resourceZipIn = new ZipInputStream(resourceFileIn);
ZipEntry testEntry;
while ((testEntry = resourceZipIn.getNextEntry()) != null) {
if (testEntry.getName().equals("background.png")) {
BufferedImage bgEntry = ImageIO.read(resourceZipIn);
}
}
因此,我猜我的代码在从java.util.zip.ZipInputStream
中提取字节并将其放回以读取图像时出现了一些问题。但是我对操纵流很陌生,所以我无法弄清楚究竟是什么问题。我想问一下是否有人可以指出我在代码中犯了哪些错误导致错误。
答案 0 :(得分:1)
read
方法不保证它填充字节数组;它只读取一个小块并返回它读取的字节数。你需要一个循环,或者使用一个填充数组的辅助类。
例如
DataInputStream in = new DataInputStream(resourceZipIn);
in.readFully(byteHolder);
in.close();