JAVA не в формате gzip ошибка

У меня есть входной поток, и я попытался обработать его, но он дал мне эту ошибку "не в формате gzip", но файл в формате gzip "Content-Encoding: gzip"

protected String readResponse(InputStream is) throws IOException {
StringBuffer string;
int b;
byte[] buffer;
String eol, s = null;
GZIPInputStream gis;
int read;
int index;


eol = new String(new byte[] {(byte)0, (byte)0, (byte)-1, (byte)-1});
buffer = new byte[1];
string = new StringBuffer();
while ( (b = is.read()) > 0 ) {
  buffer[0] = (byte)b;
  s = new String(buffer);
  string.append(s);
  index = string.indexOf(eol);
  if ( index > 0 && index == string.length() - 4 ) {
    break;
  }

}

System.out.println(string);

gis = new GZIPInputStream(is); << here I got the error
buffer = new byte[1024]; 

while ( (read = gis.read(buffer)) > 0 ) {
  string.append(new String(buffer, 0, read));
}
return string.toString();

}

Какие-нибудь мысли? Спасибо

4 ответа

Решение

Видя эту строку:

eol = новая строка (новый байт [] {(байт)0, (байт)0, (байт)-1, (байт)-1});

достаточно прийти к выводу: вы обречены с самого начала.

НЕ ИСПОЛЬЗУЙТЕ СТРОКУ ДЛЯ Двоичных данных.

byte с и char не имеют отношения друг к другу; то, что вы делаете здесь, примерно эквивалентно следующему:

final CharsetDecoder decoder = Charset.defaultCharset()
    .newDecoder().onMalformedInput(CodingErrorAction.REPLACE);
final ByteBuffer buf = ByteBuffer.wrap(new byte[]{...});
final CharBuffer cbuf = decoder.decode(buf);
final String eol = new String(cbuf.array());

Обратите внимание REPLACE действие. Любая не отображаемая последовательность байтов заставит декодер вывести символ замены Unicode, U + FFFD (выглядит знакомо, верно?).

Теперь попробуй и поставь REPORT вместо.

Более того, вы используете кодировку по умолчанию... которая отличается от платформы к платформе.

Ваш код должен просто прочитать поток ввода и вернуть byte массив. использовать ByteArrayOutputStream,

А если вы хотите записать в файл напрямую, это просто: используйте Files.copy(),

Во всяком случае, исправил это для вас:

// Note: return code is byte[]
protected byte[] readResponse(final InputStream in)
    throws IOException
{
    try (
        final InputStream gzin = new GzipInputSream(in);
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
    ) {
        final byte[] buf = new byte[4096];
        int bytesRead;
        while ((bytesRead = gzin.read(buf)) != -1)
            out.write(buf, 0, bytesRead);

        return out.toByteArray();
    }
}

Проблема может заключаться в том, что вы перемещаете указатель файла во входном потоке, прежде чем передать его в GZIPInputStream. GZIPInputStream ожидает, что первые несколько байтов будут стандартным заголовком.

Попробуйте переместить новый GZIPInputStream(is); перед вашим временем цикла

В вашем коде так много неправильного... Но давайте все равно попробуем. Таким образом, у вас есть заголовок ascii и после этого там должны быть gzipped части? Gzip файл всегда начинается с байтов идентификатора. Они имеют фиксированные значения "ID1 = 31 (0x1f, \037), ID2 = 139 (0x8b, \213)". Можете ли вы найти те из вашего входного потока. Там вы должны начать gzipstream.

Я проверил это с помощью файла, состоящего из нескольких строк заголовка, за которым следует пустая строка и добавленный текстовый файл в формате gzipped. Последний записывается, не раскрывается, в x.gz, распаковывается и читает оттуда, предполагая, что это текстовый файл. (Если это бинарный файл, BufferedReader не имеет смысла.)

Попытка / с ресурсами и ловушка должны быть добавлены, но это только техническая сложность.

InputStream is = ...;
StringBuilder lsb = new StringBuilder();
int c = -1;
while( (c = is.read()) != -1 ){
    if( c == '\n' ){
        String line = lsb.toString();
        if( line.matches( "\\s*" ) ){
            break;
        }
        System.out.println( line );
        lsb.delete( 0, lsb.length() );
    } else {
        lsb.append( (char)c );
    }
}
byte[] buffer = new byte[1024];
int nRead = 0;
OutputStream os = new FileOutputStream( "x.gz" );
while ( (nRead = is.read(buffer, 0, buffer.length )) > 0 ) {
    os.write( buffer, 0, nRead );
}
os.close();
is.close();

InputStream gis = new GZIPInputStream( new FileInputStream( "x.gz" ) );
InputStreamReader isr = new InputStreamReader( gis );
BufferedReader br = new BufferedReader(isr);
String line;
while( (line = br.readLine()) != null ){
    System.out.println("line: " + line );
}
br.close();
Другие вопросы по тегам