2010-05-06 5 views
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은 유용한 정보를 찾지 못했습니다.

답변

3

은 각 블록에 대해 반복적으로 호출하는 대신 내부 루프에서 getInputStream()을 가져와야합니다.

+1

해결했습니다. (글쎄, 완전하지는 않지만, 적어도 내 테스트 케이스는 현재 크래시되지 않는다). 나는 그것이 왜 효과가 있었는지 궁금해? 나는 그것이 호출 될 때마다 getInputStream()이 포인터를 재설정한다고 의심한다. 그래서 나는 기본적으로 PNG의 처음 1024 바이트를 반복해서 읽고 있었다. 감사합니다. –

+1

글쎄,이게 "너는 당할 수도있다"고 생각하지 않는다. getInputStream()은 모든 호출마다 다른 스트림을 반환하므로 read() 호출시마다 스트림의 처음부터 읽습니다! 최종 버퍼에는 PNG 파일의 첫 번째 1KB 만 포함되어 여러 번 복제됩니다! – jfpoilpret

+0

@jfpoilpret & @Nathan Strong :'getInputStream()'의 소스를 보면, 둘 다 맞습니다! – trashgod

관련 문제