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 org.apache.hadoop.classification.InterfaceAudience; 024import org.apache.hadoop.classification.InterfaceStability; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.io.compress.DefaultCodec; 027import org.apache.hadoop.io.compress.zlib.*; 028import org.apache.hadoop.io.compress.zlib.ZlibDecompressor.ZlibDirectDecompressor; 029 030import static org.apache.hadoop.util.PlatformName.IBM_JAVA; 031 032/** 033 * This class creates gzip compressors/decompressors. 034 */ 035@InterfaceAudience.Public 036@InterfaceStability.Evolving 037public class GzipCodec extends DefaultCodec { 038 /** 039 * A bridge that wraps around a DeflaterOutputStream to make it 040 * a CompressionOutputStream. 041 */ 042 @InterfaceStability.Evolving 043 protected static class GzipOutputStream extends CompressorStream { 044 045 private static class ResetableGZIPOutputStream extends GZIPOutputStream { 046 private static final int TRAILER_SIZE = 8; 047 public static final String JVMVersion= System.getProperty("java.version"); 048 private static final boolean HAS_BROKEN_FINISH = 049 (IBM_JAVA && JVMVersion.contains("1.6.0")); 050 051 public ResetableGZIPOutputStream(OutputStream out) throws IOException { 052 super(out); 053 } 054 055 public void resetState() throws IOException { 056 def.reset(); 057 } 058 } 059 060 public GzipOutputStream(OutputStream out) throws IOException { 061 super(new ResetableGZIPOutputStream(out)); 062 } 063 064 /** 065 * Allow children types to put a different type in here. 066 * @param out the Deflater stream to use 067 */ 068 protected GzipOutputStream(CompressorStream out) { 069 super(out); 070 } 071 072 @Override 073 public void close() throws IOException { 074 out.close(); 075 } 076 077 @Override 078 public void flush() throws IOException { 079 out.flush(); 080 } 081 082 @Override 083 public void write(int b) throws IOException { 084 out.write(b); 085 } 086 087 @Override 088 public void write(byte[] data, int offset, int length) 089 throws IOException { 090 out.write(data, offset, length); 091 } 092 093 @Override 094 public void finish() throws IOException { 095 ((ResetableGZIPOutputStream) out).finish(); 096 } 097 098 @Override 099 public void resetState() throws IOException { 100 ((ResetableGZIPOutputStream) out).resetState(); 101 } 102 } 103 104 @Override 105 public CompressionOutputStream createOutputStream(OutputStream out) 106 throws IOException { 107 if (!ZlibFactory.isNativeZlibLoaded(conf)) { 108 return new GzipOutputStream(out); 109 } 110 return CompressionCodec.Util. 111 createOutputStreamWithCodecPool(this, conf, out); 112 } 113 114 @Override 115 public CompressionOutputStream createOutputStream(OutputStream out, 116 Compressor compressor) 117 throws IOException { 118 return (compressor != null) ? 119 new CompressorStream(out, compressor, 120 conf.getInt("io.file.buffer.size", 121 4*1024)) : 122 createOutputStream(out); 123 } 124 125 @Override 126 public Compressor createCompressor() { 127 return (ZlibFactory.isNativeZlibLoaded(conf)) 128 ? new GzipZlibCompressor(conf) 129 : null; 130 } 131 132 @Override 133 public Class<? extends Compressor> getCompressorType() { 134 return ZlibFactory.isNativeZlibLoaded(conf) 135 ? GzipZlibCompressor.class 136 : null; 137 } 138 139 @Override 140 public CompressionInputStream createInputStream(InputStream in) 141 throws IOException { 142 return CompressionCodec.Util. 143 createInputStreamWithCodecPool(this, conf, in); 144 } 145 146 @Override 147 public CompressionInputStream createInputStream(InputStream in, 148 Decompressor decompressor) 149 throws IOException { 150 if (decompressor == null) { 151 decompressor = createDecompressor(); // always succeeds (or throws) 152 } 153 return new DecompressorStream(in, decompressor, 154 conf.getInt("io.file.buffer.size", 4*1024)); 155 } 156 157 @Override 158 public Decompressor createDecompressor() { 159 return (ZlibFactory.isNativeZlibLoaded(conf)) 160 ? new GzipZlibDecompressor() 161 : new BuiltInGzipDecompressor(); 162 } 163 164 @Override 165 public Class<? extends Decompressor> getDecompressorType() { 166 return ZlibFactory.isNativeZlibLoaded(conf) 167 ? GzipZlibDecompressor.class 168 : BuiltInGzipDecompressor.class; 169 } 170 171 @Override 172 public DirectDecompressor createDirectDecompressor() { 173 return ZlibFactory.isNativeZlibLoaded(conf) 174 ? new ZlibDecompressor.ZlibDirectDecompressor( 175 ZlibDecompressor.CompressionHeader.AUTODETECT_GZIP_ZLIB, 0) : null; 176 } 177 178 @Override 179 public String getDefaultExtension() { 180 return ".gz"; 181 } 182 183 static final class GzipZlibCompressor extends ZlibCompressor { 184 public GzipZlibCompressor() { 185 super(ZlibCompressor.CompressionLevel.DEFAULT_COMPRESSION, 186 ZlibCompressor.CompressionStrategy.DEFAULT_STRATEGY, 187 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 64*1024); 188 } 189 190 public GzipZlibCompressor(Configuration conf) { 191 super(ZlibFactory.getCompressionLevel(conf), 192 ZlibFactory.getCompressionStrategy(conf), 193 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 194 64 * 1024); 195 } 196 } 197 198 static final class GzipZlibDecompressor extends ZlibDecompressor { 199 public GzipZlibDecompressor() { 200 super(ZlibDecompressor.CompressionHeader.AUTODETECT_GZIP_ZLIB, 64*1024); 201 } 202 } 203 204}