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 019 package org.apache.hadoop.io.compress; 020 021 import java.io.*; 022 import java.util.zip.GZIPOutputStream; 023 import org.apache.hadoop.classification.InterfaceAudience; 024 import org.apache.hadoop.classification.InterfaceStability; 025 import org.apache.hadoop.conf.Configuration; 026 import org.apache.hadoop.io.compress.DefaultCodec; 027 import org.apache.hadoop.io.compress.zlib.*; 028 import org.apache.hadoop.io.compress.zlib.ZlibDecompressor.ZlibDirectDecompressor; 029 030 import static org.apache.hadoop.util.PlatformName.IBM_JAVA; 031 032 /** 033 * This class creates gzip compressors/decompressors. 034 */ 035 @InterfaceAudience.Public 036 @InterfaceStability.Evolving 037 public 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 return (ZlibFactory.isNativeZlibLoaded(conf)) ? 108 new CompressorStream(out, createCompressor(), 109 conf.getInt("io.file.buffer.size", 4*1024)) : 110 new GzipOutputStream(out); 111 } 112 113 @Override 114 public CompressionOutputStream createOutputStream(OutputStream out, 115 Compressor compressor) 116 throws IOException { 117 return (compressor != null) ? 118 new CompressorStream(out, compressor, 119 conf.getInt("io.file.buffer.size", 120 4*1024)) : 121 createOutputStream(out); 122 } 123 124 @Override 125 public Compressor createCompressor() { 126 return (ZlibFactory.isNativeZlibLoaded(conf)) 127 ? new GzipZlibCompressor(conf) 128 : null; 129 } 130 131 @Override 132 public Class<? extends Compressor> getCompressorType() { 133 return ZlibFactory.isNativeZlibLoaded(conf) 134 ? GzipZlibCompressor.class 135 : null; 136 } 137 138 @Override 139 public CompressionInputStream createInputStream(InputStream in) 140 throws IOException { 141 return createInputStream(in, null); 142 } 143 144 @Override 145 public CompressionInputStream createInputStream(InputStream in, 146 Decompressor decompressor) 147 throws IOException { 148 if (decompressor == null) { 149 decompressor = createDecompressor(); // always succeeds (or throws) 150 } 151 return new DecompressorStream(in, decompressor, 152 conf.getInt("io.file.buffer.size", 4*1024)); 153 } 154 155 @Override 156 public Decompressor createDecompressor() { 157 return (ZlibFactory.isNativeZlibLoaded(conf)) 158 ? new GzipZlibDecompressor() 159 : new BuiltInGzipDecompressor(); 160 } 161 162 @Override 163 public Class<? extends Decompressor> getDecompressorType() { 164 return ZlibFactory.isNativeZlibLoaded(conf) 165 ? GzipZlibDecompressor.class 166 : BuiltInGzipDecompressor.class; 167 } 168 169 @Override 170 public DirectDecompressor createDirectDecompressor() { 171 return ZlibFactory.isNativeZlibLoaded(conf) 172 ? new ZlibDecompressor.ZlibDirectDecompressor( 173 ZlibDecompressor.CompressionHeader.AUTODETECT_GZIP_ZLIB, 0) : null; 174 } 175 176 @Override 177 public String getDefaultExtension() { 178 return ".gz"; 179 } 180 181 static final class GzipZlibCompressor extends ZlibCompressor { 182 public GzipZlibCompressor() { 183 super(ZlibCompressor.CompressionLevel.DEFAULT_COMPRESSION, 184 ZlibCompressor.CompressionStrategy.DEFAULT_STRATEGY, 185 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 64*1024); 186 } 187 188 public GzipZlibCompressor(Configuration conf) { 189 super(ZlibFactory.getCompressionLevel(conf), 190 ZlibFactory.getCompressionStrategy(conf), 191 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 192 64 * 1024); 193 } 194 } 195 196 static final class GzipZlibDecompressor extends ZlibDecompressor { 197 public GzipZlibDecompressor() { 198 super(ZlibDecompressor.CompressionHeader.AUTODETECT_GZIP_ZLIB, 64*1024); 199 } 200 } 201 202 }