1
Java 응용 프로그램에 보관 파일에서 직접 ImageIcon 자원으로로드하려고하는 여러 PNG 이미지가 포함 된 ZIP 파일이 있습니다. 여기에 내 코드입니다 : entry.getSize에 의해보고ZIP 보관함에서 ImageIcon 개체를 만들려고 할 때 "crc corruption"이 발생했습니다.
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());
}
}
}
크기()는 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 바이트를 반복해서 읽고 있었다. 감사합니다. –
글쎄,이게 "너는 당할 수도있다"고 생각하지 않는다. getInputStream()은 모든 호출마다 다른 스트림을 반환하므로 read() 호출시마다 스트림의 처음부터 읽습니다! 최종 버퍼에는 PNG 파일의 첫 번째 1KB 만 포함되어 여러 번 복제됩니다! – jfpoilpret
@jfpoilpret & @Nathan Strong :'getInputStream()'의 소스를 보면, 둘 다 맞습니다! – trashgod