web123456

: Not in GZIP format exception causes and solutions

Problem: In useGZIP compression and decompression: Not in GZIP format exception may appear.

Cause: When using GZIP for compression, when creating a GZIPOutputStream object, a writeHeader method is called, which writes the header information of GZIP in the output stream. The code is as follows:

private void writeHeader() throws IOException {
        (new byte[] {
                      (byte) GZIP_MAGIC,        // Magic number (short)
                      (byte)(GZIP_MAGIC >> 8),  // Magic number (short)
                      ,        // 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)
                  });
    }

The first two bytes in the header information are used to store magic numbers. The GZIP_MAGIC value is 35615. The first byte stores the low bit and the second byte stores the high bit. When decompressed, GZIPInputStream will call readheader to read header. The code is as follows:

    private int readHeader(InputStream this_in) throws IOException {
        CheckedInputStream in = new CheckedInputStream(this_in, crc);
        ();
        // 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)() & 0xffff;
            if (readUShort(in) != v) {
                throw new ZipException("Corrupt GZIP header");
            }
            n += 2;
        }
        ();
        return n;
    }

GZIPInputStream first reads the first two bytes through readUShort and then compares it with the magic number. If the same means that the current byte array is a byte array in GZIP format. If the same means that the current byte array is not an array in GZIP format, then an exception will be thrown: Not in GZIP format.

Conclusion: When using GZIP for compression and decompression, if the compressedByte array changes during transmissionThis exception will occur, so if you do not directly transfer the compressed byte array but a string, when converting it to a string, you must use single-byte encoding such as ISO-8859-1. Otherwise, when converting the string to a byte array, the section array will change, resulting in the exception.