代码之家  ›  专栏  ›  技术社区  ›  Nathan Strong

尝试从zip存档创建ImageIcon对象时出现pngeexception“crc corrupt”

  •  1
  • Nathan Strong  · 技术社区  · 15 年前

    我有一个zip文件,其中包含大量的PNG图像,我试图直接从存档中加载到我的Java应用程序中作为IMAIGION资源。以下是我的代码:

    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)
    

    有人能解释一下吗?谷歌没有找到任何有用的信息。

    1 回复  |  直到 15 年前
        1
  •  3
  •   trashgod    15 年前

    可以 必须拉动 getInputStream() 在内部循环之外,而不是为每个块重复调用它。