I've got an inputstream which I want to zip. But the results has to be an inputstream also. Is this possible? Because if I understood some tutorials correctly, you will get an outputstream if you zip an inputstream (for example: a file).
You want to compress the input stream coming in and pass it along as an InputStream? I'm thinking of something like a stream filter. Look at the piped I/O stream classes. Maybe you can construct a ZipOutputStream around a piped outputstream that's connect to a piped input stream that you pass along. The problem here is you get into Threads because you would want to write or convert the original InputStream in a separate thread that you start and then pass the piped input stream along.
That's off of my head and there are some problems with the code no doubt. For one you'd have to know who's responsible for flushing and closing the streams. But the basic idea is you put the logic to read from the original stream and write to the Zipoutput stream (constructed around the pipedOutput) in the ZipStreamConverter class that I didn't show. (Exercise left to the reader.) Am I close to what you wanted?
The alternative approach is to create a custom input stream that wraps an InputStream and implements the zip compression algorithm as it reads from the wrapped stream. That logic would either be inlined or delegated to some class that I don't think exists in the JDK. In other words you'd probably have to implement the compression logic. I'm sure there's an object you can talk to directly but I'm not clever enough to find it. [ June 09, 2006: Message edited by: Clifton Craig ]
Thank you Clifton Craig. As I expected there's no easy solution, but what you described is exactly what I need. I will try your first approach first. I already have something similar in my program, using piped input/outputstream to turn an outputstream to an inputstream, but I was wondering if there wasn't an easy solution.
I didn't just pick GZipOutputStream because it looked good in the API docs. I picked it because I had read this article which described a servlet filter that automatically compressed responses, and it sounded a lot like your requirements.
Edit: On the other hand, if you don't just need compressed data, you need data that looks like a file in the ZIP format, then I think you are condemned to using one of those complex solutions. [ June 09, 2006: Message edited by: Paul Clapham ]
posted 14 years ago
I'm glad I could help. I still wonder if there's an easy way to apply the Zip algorithm without fiddling with threads. One idea off my mind would be to try to buffer x amount of bytes in an InputStreamZipFilter class, push a block of data from the wrapped InputStream through a ZipOutputStream instance that writes to a ByteArrayInputStream instance that feeds the buffer and as bytes are requested from the caller return the converted bytes from the byte array buffer. The problem there would be determining how big the byte array should be vs. how big the block size on each read should be when the buffer is exhausted. It would all be experimental and need to be toyed with to get it right. There's gotta be a better way to do it though.