0

ZIP ファイル内の XML ファイルと画像ファイルを読み取る必要がある Java アプレットを作成しています。Zip ファイルは HTTP 経由でダウンロードされ、アプレットは署名されていないため、使用java.util.zip.ZipInputStreamしてデータを操作する必要があります。Zip ファイル内の PNG ファイルを読み込もうとすると問題が発生します。

Zipファイルを処理する手順:

  1. Http を使用して Zip をダウンロードする

    URL resourceURL = new URL(source);
    HttpURLConnection httpConnection= (HttpURLConnection) resourceURL.openConnection();
    httpConnection.connect();
    InputStream resourceFileIn = httpConnection.getInputStream();
    
  2. ZipInputStream を使用して、ダウンロードしたデータを保持します

    ZipInputStream resourceZipIn = new ZipInputStream(resourceFileIn);
    
  3. すべての ZipEntry を繰り返し処理し、対応するバイト配列を抽出します

    ArrayList<ExtractedEntry> extractedList = new ArrayList<ExtractedEntry>();
    ZipEntry currentEntry;
    while ((currentEntry = resourceZipIn.getNextEntry()) != null) {
        byte[] byteHolder = new byte[(int) currentEntry.getSize()];
        resourceZipIn.read(byteHolder, 0, byteHolder.length);
        extractedList.add(new ExtractedEntry(currentEntry.getName(), byteHolder));
    }
    

    備考: 抽出されたすべての ZipEntry は、次のクラスによって保持されます

    public class ExtractedEntry {
        private String name;
        private byte[] byteArray;
    
        public ExtractedEntry(String name, byte[] byteArray) {
            super();
            this.name = name;
            this.byteArray = byteArray;
        }
    
        public String getName() {
            return name;
        }
    
        public byte[] getByteArray() {
            return byteArray;
        }
    }
    
  4. 抽出したリストから読みたいファイルを探す

    ExtractedEntry bgEntry = null;
    for (int j = 0; j < extractedList.size() && bgEntry == null; j++) {
        if (extractedList.get(j).getName().equals("background.png")) {
            bgEntry = extractedList.get(j);
        }
    }
    
  5. 必要に応じて特定のアクションを実行する

    InputStream mapBgIn = new ByteArrayInputStream(bgEntry.getByteArray());
    BufferedImage bgEntry = ImageIO.read(bgIn);
    

問題が発生した場所であるため、PNGファイルを読み取るアクションのみをリストします。上記の方法で画像を読み取ろうとすると、手順 5 の最後の行で常に次のエラーが表示されます。

javax.imageio.IIOException: Error reading PNG image data at com.sun.imageio.plugins.png.PNGImageReader.readImage(Unknown Source)
    at com.sun.imageio.plugins.png.PNGImageReader.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at com.quadd.soft.game.wtd.lib.resource.ResourceManager.loadHttpZipRes(ResourceManager.java:685)
Caused by: javax.imageio.IIOException: Unknown row filter type (= 7)!
    at com.sun.imageio.plugins.png.PNGImageReader.decodePass(Unknown Source)
    at com.sun.imageio.plugins.png.PNGImageReader.decodeImage(Unknown Source)
    ... 29 more

ただし、手順 3 から次のように読み込めば問題ありません。

ZipInputStream resourceZipIn = new ZipInputStream(resourceFileIn);
ZipEntry testEntry;
while ((testEntry = resourceZipIn.getNextEntry()) != null) {
    if (testEntry.getName().equals("background.png")) {
        BufferedImage bgEntry = ImageIO.read(resourceZipIn);
    }
}

java.util.zip.ZipInputStreamしたがって、バイトを抽出して画像を読み取るために元に戻す際に、コードに問題があると思います。しかし、ストリームを操作するのは初めてなので、正確に何が問題なのかわかりませんでした。エラーの原因となったコードの間違いを誰かが指摘できるかどうかを尋ねたいと思います。

4

1 に答える 1

2

このreadメソッドは、バイト配列を満たすことを保証しません。小さなブロックのみを読み取り、読み取ったバイト数を返します。ループが必要か、配列を埋めるヘルパー クラスを使用します。

例えば

DataInputStream in = new DataInputStream(resourceZipIn);
in.readFully(byteHolder);
in.close();
于 2013-09-16T15:38:01.200 に答える