我有一个输入流,我试图处理它,但它给了我这个错误“不是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();
}
任何想法? 感谢
答案 0 :(得分:1)
看到这一行:
eol = new String(new byte [] {(byte)0,(byte)0,(byte)-1,(byte)-1});
足以得出结论:你从一开始就注定要失败。
不要使用字符串数据。
byte
和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
。
更重要的是,您使用默认字符集...这在平台之间有所不同。
您的代码应该只是读取输入流并返回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();
}
}
答案 1 :(得分:0)
问题可能是你在将输入流传递给GZIPInputStream之前推进了输入流中的文件指针。 GZIPInputStream期望前几个字节是标准头。
尝试移动新的GZIPInputStream(是);在你的while循环之前
答案 2 :(得分:0)
您的代码中存在许多错误.....但无论如何都要尝试。 所以你有ascii标题,然后有zzipped部分吗? Gzip文件始终以id字节开头。它们具有固定值&#39; ID1 = 31(0x1f,\ 037),ID2 = 139(0x8b,\ 213)&#39;。你能从输入流中找到那些。那里你应该启动gzipstream。
答案 3 :(得分:0)
我用一个由几个标题行组成的文件,后面跟一个空行和一个附加的gzip压缩文本文件来测试它。后者写成,未展开,到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();