JAVA 不是 gzip 格式错误
JAVA not in gzip format error
我有一个输入流,我试图处理它,但它给了我这个错误 "not in gzip format" 但文件是 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();
}
有什么想法吗?
谢谢
问题可能是在将文件指针传递给 GZIPInputStream 之前,您在输入流中推进了文件指针。 GZIPInputStream 期望前几个字节是标准 header.
尝试移动新的 GZIPInputStream(is);在你的 while 循环之前
看到这一行:
eol = new String(new byte[] {(byte)0, (byte)0, (byte)-1, (byte)-1});
足以得出一个结论:你从一开始就注定了。
不要将字符串用于二进制数据。
byte
s 和 char
s 彼此没有关系;您在这里所做的大致相当于以下内容:
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
。
此外,您使用默认字符集...因平台而异。
您的代码实际上应该只读取输入流和 return 一个 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();
}
}
你的代码中有很多错误.....但是我们还是试试吧。
所以你有 ascii header 然后应该有 gzip 部分? Gzip 文件总是以 id 字节开头。它们具有固定值 'ID1 = 31 (0x1f, 7), ID2 = 139 (0x8b, 3)'。你能从你的输入流中找到那些吗?在那里你应该启动 gzipstream。
我已经使用由几行 header 行组成的文件进行了测试,后跟一个空行和一个附加的 gzip 文本文件。后者被写入,未扩展,到 x.gz 并解压缩并从那里读取,假设它是一个文本文件。 (如果是二进制文件,BufferedReader 是没有意义的。)
try/with 应该添加资源和捕获,但这只是技术问题。
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();
我有一个输入流,我试图处理它,但它给了我这个错误 "not in gzip format" 但文件是 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();
}
有什么想法吗? 谢谢
问题可能是在将文件指针传递给 GZIPInputStream 之前,您在输入流中推进了文件指针。 GZIPInputStream 期望前几个字节是标准 header.
尝试移动新的 GZIPInputStream(is);在你的 while 循环之前
看到这一行:
eol = new String(new byte[] {(byte)0, (byte)0, (byte)-1, (byte)-1});
足以得出一个结论:你从一开始就注定了。
不要将字符串用于二进制数据。
byte
s 和 char
s 彼此没有关系;您在这里所做的大致相当于以下内容:
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
。
此外,您使用默认字符集...因平台而异。
您的代码实际上应该只读取输入流和 return 一个 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();
}
}
你的代码中有很多错误.....但是我们还是试试吧。 所以你有 ascii header 然后应该有 gzip 部分? Gzip 文件总是以 id 字节开头。它们具有固定值 'ID1 = 31 (0x1f, 7), ID2 = 139 (0x8b, 3)'。你能从你的输入流中找到那些吗?在那里你应该启动 gzipstream。
我已经使用由几行 header 行组成的文件进行了测试,后跟一个空行和一个附加的 gzip 文本文件。后者被写入,未扩展,到 x.gz 并解压缩并从那里读取,假设它是一个文本文件。 (如果是二进制文件,BufferedReader 是没有意义的。)
try/with 应该添加资源和捕获,但这只是技术问题。
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();