blob: 7d30ae8d6920db9b3d903d33513d9273f62547eb [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.util.zip;
import java.io.IOException;
import java.io.OutputStream;
/**
* The {@code GZIPOutputStream} class is used to write data to a stream in the
* GZIP storage format.
*
* <h3>Example</h3>
* <p>Using {@code GZIPOutputStream} is a little easier than {@link ZipOutputStream}
* because GZIP is only for compression, and is not a container for multiple files.
* This code creates a GZIP stream, similar to the {@code gzip(1)} utility.
* <pre>
* OutputStream os = ...
* byte[] bytes = ...
* GZIPOutputStream zos = new GZIPOutputStream(new BufferedOutputStream(os));
* try {
* zos.write(bytes);
* } finally {
* zos.close();
* }
* </pre>
*/
public class GZIPOutputStream extends DeflaterOutputStream {
/**
* The checksum algorithm used when treating uncompressed data.
*/
protected CRC32 crc = new CRC32();
/**
* Construct a new {@code GZIPOutputStream} to write data in GZIP format to
* the underlying stream.
*
* @param os
* the {@code OutputStream} to write data to.
* @throws IOException
* if an {@code IOException} occurs.
*/
public GZIPOutputStream(OutputStream os) throws IOException {
this(os, BUF_SIZE);
}
/**
* Construct a new {@code GZIPOutputStream} to write data in GZIP format to
* the underlying stream. Set the internal compression buffer to size
* {@code size}.
*
* @param os
* the {@code OutputStream} to write to.
* @param size
* the internal buffer size.
* @throws IOException
* if an {@code IOException} occurs.
*/
public GZIPOutputStream(OutputStream os, int size) throws IOException {
super(os, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size);
writeShort(GZIPInputStream.GZIP_MAGIC);
out.write(Deflater.DEFLATED);
out.write(0); // flags
writeLong(0); // mod time
out.write(0); // extra flags
out.write(0); // operating system
}
/**
* Indicates to the stream that all data has been written out, and any GZIP
* terminal data can now be written.
*
* @throws IOException
* if an {@code IOException} occurs.
*/
@Override
public void finish() throws IOException {
super.finish();
writeLong(crc.getValue());
writeLong(crc.tbytes);
}
/**
* Write up to nbytes of data from the given buffer, starting at offset off,
* to the underlying stream in GZIP format.
*/
@Override
public void write(byte[] buffer, int off, int nbytes) throws IOException {
super.write(buffer, off, nbytes);
crc.update(buffer, off, nbytes);
}
private long writeLong(long i) throws IOException {
// Write out the long value as an unsigned int
int unsigned = (int) i;
out.write(unsigned & 0xFF);
out.write((unsigned >> 8) & 0xFF);
out.write((unsigned >> 16) & 0xFF);
out.write((unsigned >> 24) & 0xFF);
return i;
}
private int writeShort(int i) throws IOException {
out.write(i & 0xFF);
out.write((i >> 8) & 0xFF);
return i;
}
}