1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.util.zip; 19 20import java.io.IOException; 21import java.io.OutputStream; 22 23/** 24 * The {@code GZIPOutputStream} class is used to write data to a stream in the 25 * GZIP storage format. 26 * 27 * <h3>Example</h3> 28 * <p>Using {@code GZIPOutputStream} is a little easier than {@link ZipOutputStream} 29 * because GZIP is only for compression, and is not a container for multiple files. 30 * This code creates a GZIP stream, similar to the {@code gzip(1)} utility. 31 * <pre> 32 * OutputStream os = ... 33 * byte[] bytes = ... 34 * GZIPOutputStream zos = new GZIPOutputStream(new BufferedOutputStream(os)); 35 * try { 36 * zos.write(bytes); 37 * } finally { 38 * zos.close(); 39 * } 40 * </pre> 41 */ 42public class GZIPOutputStream extends DeflaterOutputStream { 43 44 /** 45 * The checksum algorithm used when treating uncompressed data. 46 */ 47 protected CRC32 crc = new CRC32(); 48 49 /** 50 * Construct a new {@code GZIPOutputStream} to write data in GZIP format to 51 * the underlying stream. 52 * 53 * @param os 54 * the {@code OutputStream} to write data to. 55 * @throws IOException 56 * if an {@code IOException} occurs. 57 */ 58 public GZIPOutputStream(OutputStream os) throws IOException { 59 this(os, BUF_SIZE); 60 } 61 62 /** 63 * Construct a new {@code GZIPOutputStream} to write data in GZIP format to 64 * the underlying stream. Set the internal compression buffer to size 65 * {@code size}. 66 * 67 * @param os 68 * the {@code OutputStream} to write to. 69 * @param size 70 * the internal buffer size. 71 * @throws IOException 72 * if an {@code IOException} occurs. 73 */ 74 public GZIPOutputStream(OutputStream os, int size) throws IOException { 75 super(os, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size); 76 writeShort(GZIPInputStream.GZIP_MAGIC); 77 out.write(Deflater.DEFLATED); 78 out.write(0); // flags 79 writeLong(0); // mod time 80 out.write(0); // extra flags 81 out.write(0); // operating system 82 } 83 84 /** 85 * Indicates to the stream that all data has been written out, and any GZIP 86 * terminal data can now be written. 87 * 88 * @throws IOException 89 * if an {@code IOException} occurs. 90 */ 91 @Override 92 public void finish() throws IOException { 93 super.finish(); 94 writeLong(crc.getValue()); 95 writeLong(crc.tbytes); 96 } 97 98 /** 99 * Write up to nbytes of data from the given buffer, starting at offset off, 100 * to the underlying stream in GZIP format. 101 */ 102 @Override 103 public void write(byte[] buffer, int off, int nbytes) throws IOException { 104 super.write(buffer, off, nbytes); 105 crc.update(buffer, off, nbytes); 106 } 107 108 private long writeLong(long i) throws IOException { 109 // Write out the long value as an unsigned int 110 int unsigned = (int) i; 111 out.write(unsigned & 0xFF); 112 out.write((unsigned >> 8) & 0xFF); 113 out.write((unsigned >> 16) & 0xFF); 114 out.write((unsigned >> 24) & 0xFF); 115 return i; 116 } 117 118 private int writeShort(int i) throws IOException { 119 out.write(i & 0xFF); 120 out.write((i >> 8) & 0xFF); 121 return i; 122 } 123} 124