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