How do I get the InputStream of decompressed data from an InputStream of GZIPed data?

风流意气都作罢 提交于 2019-12-08 16:09:07

问题


I call a service which returns a gzipped file. I have the data as an InputStream (courtesy of javax.activation.DataHandler.getInputStream();) from the response.

What I would like to do is, without writing anything to disk, get an InputStream of the decompressed data in the file that is in the archive. The compressed file in this case is an xml document that I am trying to unmarshal using javax.xml.bind.Unmarshaller which takes an InputStream.

I'm currently trying to write the InputStream to an OutputStream (decompressing the data) and then I'll need to write it back to an InputStream. It's not working yet so I thought I would see if there was a better (I would hope so) approach.

I can write the initial InputStream to disk and get a gz file, and then read that file, get the compressed file out of it and go from there but I'd rather keep it all in memory is possible.

Update 1: Here is my current (not working - get a "Not in GZIP format" exception):

    ByteArrayInputStream xmlInput = null;
    try {
        InputStream in = dh.getInputStream(); //dh is a javax.activation.DataHandler
        BufferedInputStream bis = new BufferedInputStream(in);
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        int bytes_read = 0;
        byte[] dataBuf = new byte[4096];
        while ((bytes_read = bis.read(dataBuf)) != -1) {
            bo.write(dataBuf, 0, bytes_read);
        }
        ByteArrayInputStream bin = new ByteArrayInputStream(bo.toByteArray());
        GZIPInputStream gzipInput = new GZIPInputStream(bin);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        dataBuf = new byte[4096];;
        bytes_read = 0;
        while ((bytes_read = gzipInput.read(dataBuf)) > 0) {
            out.write(dataBuf, 0, bytes_read);
        }
        xmlInput = new ByteArrayInputStream(out.toByteArray());

If instead of writing to a ByteArrayOutputStream I write to a FileOutputStream the first time around I get a compressed file (which I can manually open to get the xml file within) and the service (eBay) says it should be a gzip file so I'm not sure why I get a "Not in GZIP format" error.

Update 2: I tried something a little different - same error ("Not in GZIP format"). Wow, I just tried to end that parenthesis with a semi-colon. Anyways, here is my second attempt, which still does not work:

    ByteArrayInputStream xmlInput = null;
    try {
        GZIPInputStream gzipInput = new GZIPInputStream(dh.getInputStream());
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        int bytes_read = 0;
        byte[] dataBuf = new byte[4096];
        while ((bytes_read = gzipInput.read(dataBuf)) != -1) {
            bo.write(dataBuf, 0, bytes_read);
        }
        xmlInput = new ByteArrayInputStream(bo.toByteArray());

回答1:


The following code should work. Keep in mind you'll have to handle exceptions properly.

OutputStream out = null;
InputStream in = null;
try {
   out = /* some output stream */;
   in = new java.util.GZIPInputStream(/*some stream*/);
   byte[] buffer = new byte[4096];
   int c = 0;
   while (( c = in.read(buffer, 0, 4096)) > 0) {
      out.write(buffer, 0, c);
   }
} finally {
   if (in != null) {
      in.close();
   }
   if (out != null) {
      out.close();
   }
}



回答2:


Decorate the input stream with a GZIPInputStream.

InputStream decompressed = new GZIPInputStream(compressed);



回答3:


Take a look at GZIPInputStream. Here's an example; the class handles this very transparently, it's almost no work to use.



来源:https://stackoverflow.com/questions/1744290/how-do-i-get-the-inputstream-of-decompressed-data-from-an-inputstream-of-gziped

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!