我已经使用了一段时间来从网络服务器上获取数据的一些代码,几个月前,我添加了压缩支持,这似乎适用于“常规”HTTP响应,其中整个文件包含在回复中。但是,当我使用Range
标题时,它似乎不起作用。
以下是执行实际工作的代码:
InputStream in = null;
int bufferSize = 4096;
int responseCode = conn.getResponseCode();
boolean error = 5 == responseCode / 100
|| 4 == responseCode / 100;
int bytesRead = 0;
try
{
if(error)
in = conn.getErrorStream();
else
in = conn.getInputStream();
// Buffer the input
in = new BufferedInputStream(in);
// Handle compressed responses
if("gzip".equalsIgnoreCase(conn.getHeaderField("Content-Encoding")))
in = new GZIPInputStream(in);
else if("deflate".equalsIgnoreCase(conn.getHeaderField("Content-Encoding")))
in = new InflaterInputStream(in, new Inflater(true));
int n;
byte[] buffer = new byte[bufferSize];
// Now, just write out all the bytes
while(-1 != (n = in.read(buffer)))
{
bytesRead += n;
out.write(buffer, 0, n);
}
}
catch (IOException ioe)
{
System.err.println("Got IOException after reading " + bytesRead + " bytes");
throw ioe;
}
finally
{
if(null != in) try { in.close(); }
catch (IOException ioe)
{
System.err.println("Could not close InputStream");
ioe.printStackTrace();
}
}
点击带有标题Accept-Encoding: gzip,deflate,identity
的URL效果很好:我可以看到服务器以压缩格式返回数据,上面的代码很好地解压缩了。
如果我然后添加Range: bytes=0-50
标头,我会收到以下异常:
Got IOException after reading 0 bytes
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:116)
at java.io.FilterInputStream.read(FilterInputStream.java:107)
at [my code]([my code]:511)
我的代码中的行511
是包含in.read()
调用的行。响应包括以下标题:
Content-Type: text/html
Content-Encoding: gzip
Content-Range: bytes 0-50/751
Content-Length: 51
我已经验证过,如果我不尝试解压缩响应,我实际上在响应中得到51个字节......这不是服务器故障(至少我可以告诉)。我的服务器(Apache httpd)不支持“deflate”,所以我无法测试另一种压缩方案(至少现在不行)。
我还试图请求更多的数据(比如目标资源中总共751个字节的700个字节),我得到了同样的错误。
我有什么遗失的吗?
更新 对不起,我忘了在Linux上使用Apache / 2.2.22。没有任何我知道的服务器错误。我在验证从服务器检索的压缩字节时会遇到一些麻烦,因为“gzip”内容编码非常简单......例如我相信我不能只在命令行上使用“gunzip”来解压缩这些字节。不过我会尝试一下。
答案 0 :(得分:1)
您可以使用'gunzip'对其进行解压缩,请记住,前50个字节可能不足以让gzip解压缩任何内容(标题,字典等)。试试这个:wget -O- -q <URL> | head -c 50 | zcat
和你的网址,看看普通的gzip是否适用于代码失败的地方。
答案 1 :(得分:0)
叹息切换到另一台服务器(恰好运行Apache / 2.2.25)表明我的代码实际上工作正常。原始目标服务器似乎受到AWS在US-EAST可用区中当前中断的影响。我将把这一点归结为网络错误并关闭这个问题。感谢那些提出建议的人。