Как получить InputStream распакованных данных из InputStream GZIP-данных? - PullRequest
9 голосов
/ 16 ноября 2009

Я звоню в службу, которая возвращает сжатый файл. У меня есть данные как InputStream (любезно предоставлено javax.activation.DataHandler.getInputStream();) из ответа.

Я бы хотел, не записывая ничего на диск, получить InputStream распакованных данных в файле, который находится в архиве. Сжатый файл в этом случае представляет собой XML-документ, который я пытаюсь распаковать, используя javax.xml.bind.Unmarshaller, который принимает InputStream.

В настоящее время я пытаюсь записать InputStream в OutputStream (распаковка данных), а затем мне нужно будет записать его обратно в InputStream. Это еще не работает, поэтому я подумал, что увижу, есть ли лучший (я бы так надеялся) подход.

Я могу записать исходный InputStream на диск и получить файл gz, а затем прочитать этот файл, извлечь из него сжатый файл и перейти оттуда, но я бы предпочел сохранить все это в памяти.

Обновление 1. Вот мой текущий (не работает - получите исключение «Не в формате GZIP»):

    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());

Если вместо записи в ByteArrayOutputStream я в первый раз пишу в FileOutputStream, то получаю сжатый файл (который я могу открыть вручную, чтобы получить файл XML), а служба (eBay) говорит, что это должен быть файл gzip поэтому я не уверен, почему я получаю сообщение об ошибке «Не в формате GZIP».

Обновление 2: я попробовал что-то немного другое - та же ошибка («Не в формате GZIP»). Вау, я просто попытался завершить эту скобку точкой с запятой. В любом случае, вот моя вторая попытка, которая все еще не работает:

    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());

Ответы [ 3 ]

4 голосов
/ 16 ноября 2009

Украсить входной поток с помощью GZIPInputStream.

InputStream decompressed = new GZIPInputStream(compressed);
2 голосов
/ 16 ноября 2009

Следующий код должен работать. Имейте в виду, что вам придется правильно обрабатывать исключения.

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();
   }
}
0 голосов
/ 16 ноября 2009

Взгляните на GZIPInputStream. Вот пример ; класс обрабатывает это очень прозрачно, его практически невозможно использовать.

...