Compress an InputStream with gzip

前端 未结 12 1433
迷失自我
迷失自我 2020-12-29 05:28

I would like to compress an input stream in java using Gzip compression.

Let\'s say we have an input stream (1GB of data..) not compressed. I want as a result a comp

12条回答
  •  醉话见心
    2020-12-29 06:13

    If you dont want to load content into large byte array and need true streaming solution :

    package x.y.z;
    
    import org.apache.commons.io.IOUtils;
    
    import java.io.*;
    import java.util.Arrays;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.zip.GZIPInputStream;
    import java.util.zip.GZIPOutputStream;
    import java.util.zip.ZipOutputStream;
    
    /**
     * Stream Compression Utility
     *
     * @author Thamme Gowda N
     */
    public enum CompressionUtil {
        INSTANCE;
    
        public static final int NUM_THREADS = 5;
        private final ExecutorService pool;
    
        CompressionUtil(){
            this.pool = Executors.newFixedThreadPool(NUM_THREADS);
        }
    
        public static CompressionUtil getInstance(){
            return INSTANCE;
        }
    
        /**
         * Supported compression type names
         */
        public static enum CompressionType {
            GZIP,
            ZIP
        }
    
        /**
         * Wraps the given stream in a Compressor stream based on given type
         * @param sourceStream : Stream to be wrapped
         * @param type         : Compression type
         * @return source stream wrapped in a compressor stream
         * @throws IOException when some thing bad happens
         */
        public static OutputStream getCompressionWrapper(OutputStream sourceStream,
                                         CompressionType type) throws IOException {
    
            switch (type) {
                case GZIP:
                    return new GZIPOutputStream(sourceStream);
                case ZIP:
                    return new ZipOutputStream(sourceStream);
                default:
                    throw new IllegalArgumentException("Possible values :"
                            + Arrays.toString(CompressionType.values()));
            }
        }
    
        /**
         * Gets Compressed Stream for given input Stream
         * @param sourceStream  : Input Stream to be compressed to
         * @param type: Compression types such as GZIP
         * @return  Compressed Stream
         * @throws IOException when some thing bad happens
         */
        public static InputStream getCompressedStream(final InputStream sourceStream,
                                        CompressionType type ) throws IOException {
    
            if(sourceStream == null) {
                throw new IllegalArgumentException("Source Stream cannot be NULL");
            }
    
            /**
             *  sourceStream --> zipperOutStream(->intermediateStream -)--> resultStream
             */
            final PipedInputStream resultStream = new PipedInputStream();
            final PipedOutputStream intermediateStream = new PipedOutputStream(resultStream);
            final OutputStream zipperOutStream = getCompressionWrapper(intermediateStream, type);
    
            Runnable copyTask = new Runnable() {
    
                @Override
                public void run() {
                    try {
                        int c;
                        while((c = sourceStream.read()) >= 0) {
                            zipperOutStream.write(c);
                        }
                        zipperOutStream.flush();
                    } catch (IOException e) {
                        IOUtils.closeQuietly(resultStream);  // close it on error case only
                        throw new RuntimeException(e);
                    } finally {
                        // close source stream and intermediate streams
                        IOUtils.closeQuietly(sourceStream);
                        IOUtils.closeQuietly(zipperOutStream);
                        IOUtils.closeQuietly(intermediateStream);
                    }
                }
            };
            getInstance().pool.submit(copyTask);
            return resultStream;
        }
    
        public static void main(String[] args) throws IOException {
            String input = "abcdefghij";
            InputStream sourceStream = new ByteArrayInputStream(input.getBytes());
            InputStream compressedStream =
                    getCompressedStream(sourceStream, CompressionType.GZIP);
    
            GZIPInputStream decompressedStream = new GZIPInputStream(compressedStream);
            List lines = IOUtils.readLines(decompressedStream);
            String output = lines.get(0);
            System.out.println("test passed ? " + input.equals(output));
    
        }
    }
    

提交回复
热议问题