1
我有一個ZIP文件,其中包含大量PNG圖像,我試圖直接從存檔中將它們加載到Java應用程序中作爲ImageIcon資源。這裏是我的代碼:嘗試從ZIP存檔中創建ImageIcon對象時PNGException「crc腐敗」
import java.io.*;
import java.util.Enumeration;
import java.util.zip.*;
import javax.swing.ImageIcon;
public class Test {
public static void main(String[] args)
{
if(args.length == 0)
{
System.out.println("usage: java Test.java file.zip");
return;
}
File archive = new File(args[0]);
if(!archive.exists() || !archive.canRead())
{
System.err.printf("Unable to find/access %s.\n", archive);
return;
}
try {
ZipFile zip = new ZipFile(archive);
Enumeration <? extends ZipEntry>e = zip.entries();
while(e.hasMoreElements())
{
ZipEntry entry = (ZipEntry) e.nextElement();
int size = (int) entry.getSize();
int count = (size % 1024 == 0) ? size/1024 : (size/1024)+1;
int offset = 0;
int nread, toRead;
byte[] buffer = new byte[size];
for(int i = 0; i < count; i++)
{
offset = 1024*i;
toRead = (size-offset > 1024) ? 1024 : size-offset;
nread = zip.getInputStream(entry).read(buffer, offset, toRead);
}
ImageIcon icon = new ImageIcon(buffer); // boom -- why?
}
zip.close();
} catch(IOException ex) {
System.err.println(ex.getMessage());
}
}
}
大小由entry.getSize()報告匹配PNG文件的未壓縮的大小,我能夠讀出歸檔的數據沒有任何異常,但對創作ImageIcon爆炸了。堆棧跟蹤:
sun.awt.image.PNGImageDecoder$PNGException: crc corruption
at sun.awt.image.PNGImageDecoder.getChunk(PNGImageDecoder.java:699)
at sun.awt.image.PNGImageDecoder.getData(PNGImageDecoder.java:707)
at sun.awt.image.PNGImageDecoder.produceImage(PNGImageDecoder.java:234)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:246)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
sun.awt.image.PNGImageDecoder$PNGException: crc corruption
at sun.awt.image.PNGImageDecoder.getChunk(PNGImageDecoder.java:699)
at sun.awt.image.PNGImageDecoder.getData(PNGImageDecoder.java:707)
at sun.awt.image.PNGImageDecoder.produceImage(PNGImageDecoder.java:234)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:246)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
任何人都可以看到它嗎? Google沒有提供任何有用的信息。
修好了! (好吧,不是完全的,但至少我的測試案例現在不會崩潰)。我想知道它爲什麼有效?我懷疑每次調用getInputStream()都會重置指針,所以我基本上一次又一次地讀取PNG的前1024個字節。 謝謝! – 2010-05-06 05:55:11
嗯,我認爲這是「你必須拉」,而不僅僅是「你可能」。它看起來getInputStream()在每次調用時都會返回一個不同的流,因此每次調用read()時都會從流的開頭讀取數據!最後緩衝區只包含PNG文件的第一個1KB,重複多次! – jfpoilpret 2010-05-06 05:55:15
@jfpoilpret&@Nathan Strong:查看getInputStream()的來源,你是對的! – trashgod 2010-05-06 15:38:20