2010-05-06 16 views
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沒有提供任何有用的信息。

回答

3

可能 必須將getInputStream()拉出內循環,而不是每個塊重複調用它。

+1

修好了! (好吧,不是完全的,但至少我的測試案例現在不會崩潰)。我想知道它爲什麼有效?我懷疑每次調用getInputStream()都會重置指針,所以我基本上一次又一次地讀取PNG的前1024個字節。 謝謝! – 2010-05-06 05:55:11

+1

嗯,我認爲這是「你必須拉」,而不僅僅是「你可能」。它看起來getInputStream()在每次調用時都會返回一個不同的流,因此每次調用read()時都會從流的開頭讀取數據!最後緩衝區只包含PNG文件的第一個1KB,重複多次! – jfpoilpret 2010-05-06 05:55:15

+0

@jfpoilpret&@Nathan Strong:查看getInputStream()的來源,你是對的! – trashgod 2010-05-06 15:38:20

相關問題