java.util.zip.ZipException:Not inGZIP形式の例外の原因と解決策



Java Util Zip Zipexception



質問:使用中 GZIPの圧縮と解凍 java.util.zip.ZipExceptionが発生する可能性があります:GZIP形式の例外ではありません。

原因:圧縮にGZIPを使用している場合、GZIPOutputStreamオブジェクトが作成されると、writeHeaderメソッドが呼び出され、GZIPヘッダー情報が出力ストリームに書き込まれます。コードは次のように表示されます。



private void writeHeader() throws IOException { out.write(new byte[] { (byte) GZIP_MAGIC, // Magic number (short) (byte)(GZIP_MAGIC >> 8), // Magic number (short) Deflater.DEFLATED, // Compression method (CM) 0, // Flags (FLG) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Modification time MTIME (int) 0, // Extra flags (XFLG) 0 // Operating system (OS) }) }

ヘッダー情報の最初の2バイトは、マジックナンバーを格納するために使用されます。 GZIP_MAGIC値は35615で、最初のバイトは下位ビットを格納し、2番目のバイトは上位ビットを格納します。解凍されると、GZIPInputStreamはreadheaderを呼び出してヘッダー情報を読み取ります。コードは次のように表示されます。

private int readHeader(InputStream this_in) throws IOException { CheckedInputStream in = new CheckedInputStream(this_in, crc) crc.reset() // Check header magic if (readUShort(in) != GZIP_MAGIC) { throw new ZipException('Not in GZIP format') } // Check compression method if (readUByte(in) != 8) { throw new ZipException('Unsupported compression method') } // Read flags int flg = readUByte(in) // Skip MTIME, XFL, and OS fields skipBytes(in, 6) int n = 2 + 2 + 6 // Skip optional extra field if ((flg & FEXTRA) == FEXTRA) { int m = readUShort(in) skipBytes(in, m) n += m + 2 } // Skip optional file name if ((flg & FNAME) == FNAME) { do { n++ } while (readUByte(in) != 0) } // Skip optional file comment if ((flg & FCOMMENT) == FCOMMENT) { do { n++ } while (readUByte(in) != 0) } // Check optional header CRC if ((flg & FHCRC) == FHCRC) { int v = (int)crc.getValue() & 0xffff if (readUShort(in) != v) { throw new ZipException('Corrupt GZIP header') } n += 2 } crc.reset() return n }

GZIPInputStreamは、最初にreadUShortを介して最初の2バイトを読み取り、それをマジックナンバーと比較します。同じことが現在のバイト配列がGZIP形式のバイト配列であることを示している場合、同じでない場合は、現在のバイト配列がGZIP形式の配列ではないことを意味します。例外java.util.zip.ZipException:GZIP形式ではありません。



結論:圧縮および解凍にGZIPを使用する場合、圧縮されている場合 送信中にバイト配列が変更される これにより、この例外が発生するため、圧縮されたバイト配列ではなく文字列を直接転送する場合は、文字列に変換するときにISO-8859-1などのシングルバイトエンコーディングを使用する必要があります。それ以外の場合は、文字列の変換バイト配列に変更すると、セクション配列が変更され、例外が発生します。