java-如何从HttpURLConnection获取gzip压缩数据的大小
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-如何从HttpURLConnection获取gzip压缩数据的大小,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3718字,纯文字阅读大概需要6分钟。
内容图文
![java-如何从HttpURLConnection获取gzip压缩数据的大小](/upload/InfoBanner/zyjiaocheng/661/4bbf9c290ae941b48c33b4b0a83dfb29.jpg)
我试图获取从URLConnection获得的数据长度.
由于我正在测量要传输的数据量,因此我不想知道未压缩数据的大小,而是要知道压缩后的数据的大小.不幸的是InputStream会自动解压缩gzip压缩的数据.
我必须手动下载整个文件,以防输出分块并且无法通过connection.getContentLength()获得长度.
代码在这里
try {
connection = (HttpURLConnection) (new URL(url)).openConnection();
connection.connect();
int contentLength = connection.getContentLength();
if (contentLength == -1 && connection != null) {
InputStream input = connection.getInputStream();
byte[] buffer = new byte[4096];
int count = 0, len;
while ((len = input.read(buffer)) > 0) {
count += len;
}
contentLength = count;
}
totalSize += contentLength;
}
您可以看到此文件的示例:http://www.google-analytics.com/analytics.js
当我在Chrome浏览器中检查标题时,它显示的是Content-Length:11181.但是,我无法通过URLConnection获得此内容长度(返回-1),因此我尝试下载该文件.但是,我的输出是25421字节,这是未压缩文件的大小.
谢谢您的帮助.
解决方法:
您必须将Accept-Encoding标头设置为“ gzip,deflate”,以使服务器知道您的客户端接受压缩数据.
String url = "https://www.google-analytics.com/analytics.js";
HttpURLConnection connection = (HttpURLConnection) (new URL(url)).openConnection();
connection.setRequestProperty("Accept-Encoding", "gzip, deflate");
connection.connect();
int contentLength = connection.getContentLength();
System.out.println("Content-Length: " + contentLength);
没有此标头,您将迫使站点返回纯文本数据.如果数据太大,则站点可能会分块返回响应,在这种情况下,响应将没有Content-Length标头.
从developer.mozilla, Transfer-Encoding, chunked开始:
Data is sent in a series of chunks. The Content-Length header is omitted in this case and at the beginning of each chunk you need to add the length of the current chunk in hexadecimal format, followed by ‘\r\n’ and then the chunk itself, followed by another ‘\r\n’. The terminating chunk is a regular chunk, with the exception that its length is zero. It is followed by the trailer, which consists of a (possibly empty) sequence of entity header fields.
如果响应是分块的,恐怕您必须读取所有数据才能知道其大小.每个块前面都带有一个十六进制数字,该数字指示块的大小.我想您可以使用此数字来计算总数据大小,但是您仍然必须读取所有数据,因此这样做没有任何好处.我们可以检查是否使用Transfer-Encoding标头对响应进行了分块.
String url = "https://www.google-analytics.com/analytics.js";
HttpURLConnection connection = (HttpURLConnection) (new URL(url)).openConnection();
connection.connect();
String transferEncoding = connection.getHeaderField("Transfer-Encoding");
System.out.println("Transfer-Encoding: " + transferEncoding);
在这种情况下,您必须将原始响应数据存储在字节数组中,以便找到压缩数据的大小.
InputStream input = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int n;
while ((n = input.read(buffer)) > 0) {
baos.write(buffer, 0, n);
}
byte[] zippedData = baos.toByteArray();
System.out.println(zippedData.length);
因此,我想出了一个“ hack”,它可能会揭示分块响应的数据大小,而无需读取它.如果我们使用Range标头,则服务器可能会响应一个Content-Range标头.此标头将包含发送的字节和内容的总字节.请注意,这不是检测内容大小的可靠方法,如果服务器不支持范围请求,则此方法将无效.
String url = "https://www.google-analytics.com/analytics.js";
HttpURLConnection connection = (HttpURLConnection) (new URL(url)).openConnection();
connection.setRequestProperty("Accept-Encoding", "gzip, deflate");
connection.setRequestProperty("Range", "bytes=0-1");
connection.connect();
int contentLength = connection.getContentLength();
String contentRange = connection.getHeaderField("Content-Range");
if (contentRange != null) {
contentLength = Integer.parseInt(contentRange.split("/")[1]);
}
System.out.println("Content-Length: " + contentLength);
内容总结
以上是互联网集市为您收集整理的java-如何从HttpURLConnection获取gzip压缩数据的大小全部内容,希望文章能够帮你解决java-如何从HttpURLConnection获取gzip压缩数据的大小所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。