001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.io.compress; 020 021import java.io.*; 022import java.util.zip.GZIPOutputStream; 023import java.util.zip.GZIPInputStream; 024 025import org.apache.hadoop.classification.InterfaceAudience; 026import org.apache.hadoop.classification.InterfaceStability; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.io.compress.DefaultCodec; 029import org.apache.hadoop.io.compress.zlib.*; 030import org.apache.hadoop.io.compress.zlib.ZlibCompressor.CompressionLevel; 031import org.apache.hadoop.io.compress.zlib.ZlibCompressor.CompressionStrategy; 032 033/** 034 * This class creates gzip compressors/decompressors. 035 */ 036@InterfaceAudience.Public 037@InterfaceStability.Evolving 038public class GzipCodec extends DefaultCodec { 039 /** 040 * A bridge that wraps around a DeflaterOutputStream to make it 041 * a CompressionOutputStream. 042 */ 043 @InterfaceStability.Evolving 044 protected static class GzipOutputStream extends CompressorStream { 045 046 private static class ResetableGZIPOutputStream extends GZIPOutputStream { 047 048 public ResetableGZIPOutputStream(OutputStream out) throws IOException { 049 super(out); 050 } 051 052 public void resetState() throws IOException { 053 def.reset(); 054 } 055 } 056 057 public GzipOutputStream(OutputStream out) throws IOException { 058 super(new ResetableGZIPOutputStream(out)); 059 } 060 061 /** 062 * Allow children types to put a different type in here. 063 * @param out the Deflater stream to use 064 */ 065 protected GzipOutputStream(CompressorStream out) { 066 super(out); 067 } 068 069 public void close() throws IOException { 070 out.close(); 071 } 072 073 public void flush() throws IOException { 074 out.flush(); 075 } 076 077 public void write(int b) throws IOException { 078 out.write(b); 079 } 080 081 public void write(byte[] data, int offset, int length) 082 throws IOException { 083 out.write(data, offset, length); 084 } 085 086 public void finish() throws IOException { 087 ((ResetableGZIPOutputStream) out).finish(); 088 } 089 090 public void resetState() throws IOException { 091 ((ResetableGZIPOutputStream) out).resetState(); 092 } 093 } 094 095 public CompressionOutputStream createOutputStream(OutputStream out) 096 throws IOException { 097 return (ZlibFactory.isNativeZlibLoaded(conf)) ? 098 new CompressorStream(out, createCompressor(), 099 conf.getInt("io.file.buffer.size", 4*1024)) : 100 new GzipOutputStream(out); 101 } 102 103 public CompressionOutputStream createOutputStream(OutputStream out, 104 Compressor compressor) 105 throws IOException { 106 return (compressor != null) ? 107 new CompressorStream(out, compressor, 108 conf.getInt("io.file.buffer.size", 109 4*1024)) : 110 createOutputStream(out); 111 } 112 113 public Compressor createCompressor() { 114 return (ZlibFactory.isNativeZlibLoaded(conf)) 115 ? new GzipZlibCompressor(conf) 116 : null; 117 } 118 119 public Class<? extends Compressor> getCompressorType() { 120 return ZlibFactory.isNativeZlibLoaded(conf) 121 ? GzipZlibCompressor.class 122 : null; 123 } 124 125 public CompressionInputStream createInputStream(InputStream in) 126 throws IOException { 127 return createInputStream(in, null); 128 } 129 130 public CompressionInputStream createInputStream(InputStream in, 131 Decompressor decompressor) 132 throws IOException { 133 if (decompressor == null) { 134 decompressor = createDecompressor(); // always succeeds (or throws) 135 } 136 return new DecompressorStream(in, decompressor, 137 conf.getInt("io.file.buffer.size", 4*1024)); 138 } 139 140 public Decompressor createDecompressor() { 141 return (ZlibFactory.isNativeZlibLoaded(conf)) 142 ? new GzipZlibDecompressor() 143 : new BuiltInGzipDecompressor(); 144 } 145 146 public Class<? extends Decompressor> getDecompressorType() { 147 return ZlibFactory.isNativeZlibLoaded(conf) 148 ? GzipZlibDecompressor.class 149 : BuiltInGzipDecompressor.class; 150 } 151 152 public String getDefaultExtension() { 153 return ".gz"; 154 } 155 156 static final class GzipZlibCompressor extends ZlibCompressor { 157 public GzipZlibCompressor() { 158 super(ZlibCompressor.CompressionLevel.DEFAULT_COMPRESSION, 159 ZlibCompressor.CompressionStrategy.DEFAULT_STRATEGY, 160 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 64*1024); 161 } 162 163 public GzipZlibCompressor(Configuration conf) { 164 super(ZlibFactory.getCompressionLevel(conf), 165 ZlibFactory.getCompressionStrategy(conf), 166 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 167 64 * 1024); 168 } 169 } 170 171 static final class GzipZlibDecompressor extends ZlibDecompressor { 172 public GzipZlibDecompressor() { 173 super(ZlibDecompressor.CompressionHeader.AUTODETECT_GZIP_ZLIB, 64*1024); 174 } 175 } 176 177}