7

I have a method like

      public void put(@Nonnull final InputStream inputStream, @Nonnull final String uniqueId) throws PersistenceException {
        // a.) create gzip of inputStream
        final GZIPInputStream zipInputStream;
        try {
            zipInputStream = new GZIPInputStream(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
            throw new PersistenceException("Persistence Service could not received input stream to persist for " + uniqueId);
        }

I wan to convert the inputStream into zipInputStream, what is the way to do that?

  • The above method is incorrect and throws Exception as "Not a Zip Format"

converting Java Streams to me are really confusing and I do not make them right

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
daydreamer
  • 87,243
  • 191
  • 450
  • 722
  • Why do you think that the provided `InputStream` returns GZIP content? The exception message clearly tells it is not. What exactly is the concrete functional requirement? Why exactly do you need to "convert" it this way? – BalusC Sep 07 '12 at 16:33
  • I need to save the document on `Amazon S3` in compressed format to save space and reduced billing, which is why the inputstream is a document that I am trying to ZIP and send to `S3` – daydreamer Sep 07 '12 at 16:35
  • 2
    Ah, that makes more sense. I've posted an answer. In the future questions, please don't forget to clearly state the concrete functional requirement. Try to ask how to solve a problem, not how to achieve a solution of which you thought that it's the right solution to the concrete problem. Otherwise the question would likely never receive a valid answer and you keep stabbing in the dark. – BalusC Sep 07 '12 at 16:49

2 Answers2

12

The GZIPInputStream is to be used to decompress an incoming InputStream. To compress an incoming InputStream using GZIP, you basically need to write it to a GZIPOutputStream.

You can get a new InputStream out of it if you use ByteArrayOutputStream to write gzipped content to a byte[] and ByteArrayInputStream to turn a byte[] into an InputStream.

So, basically:

public void put(@Nonnull final InputStream inputStream, @Nonnull final String uniqueId) throws PersistenceException {
    final InputStream zipInputStream;
    try {
        ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
        GZIPOutputStream gzipOutput = new GZIPOutputStream(bytesOutput);

        try {
            byte[] buffer = new byte[10240];
            for (int length = 0; (length = inputStream.read(buffer)) != -1;) {
                gzipOutput.write(buffer, 0, length);
            }
        } finally {
            try { inputStream.close(); } catch (IOException ignore) {}
            try { gzipOutput.close(); } catch (IOException ignore) {}
        }

        zipInputStream = new ByteArrayInputStream(bytesOutput.toByteArray());
    } catch (IOException e) {
        e.printStackTrace();
        throw new PersistenceException("Persistence Service could not received input stream to persist for " + uniqueId);
    }

    // ...

You can if necessary replace the ByteArrayOutputStream/ByteArrayInputStream by a FileOuputStream/FileInputStream on a temporary file as created by File#createTempFile(), especially if those streams can contain large data which might overflow machine's available memory when used concurrently.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
5

GZIPInputStream is for reading gzip-encoding content.

If your goal is to take a regular input stream and compress it in the GZIP format, then you need to write those bytes to a GZIPOutputStream.

See also this answer to a related question.

Community
  • 1
  • 1
matt b
  • 138,234
  • 66
  • 282
  • 345