getContentLengthLong() == -1 表示可用元数据中没有已知的内容长度。应继续读取流并显示已接收字节数或不确定的进度;不要把它当作空响应,也不要分配负长度的缓冲区。

long expected = connection.getContentLengthLong();
long received = 0;
byte[] buffer = new byte[8192];
try (InputStream input = connection.getInputStream()) {
    int count;
    while ((count = input.read(buffer)) != -1) {
        output.write(buffer, 0, count);
        received += count;
    }
}

连接已经配置好,output 归调用方所有。请在这个循环周围保留连接与读取超时以及应用的任何大小限制。I/O 错误意味着下载失败,而不是以更少字节成功完成。

在同一层面上比较长度。HTTP/1.1 的分块编码可以取代 Content-Length,并由 HTTP 实现解码。代理可能重新分帧。解压缩也可能使应用解码后的字节数与编码后的 Content-Length 不同。

如果 Transfer-Encoding 和 Content-Length 同时出现,不要挑选一个方便的数字:HTTP 分帧会让传输编码优先,并把这种组合视为可能的错误。把这类解析交给符合规范的实现。

通过 HTTP 网关访问的 FTP URL 需要检查其具体的 URLConnection 行为;它并不保证每个 HTTP 头部访问器在任何 JDK 中都像普通 HTTP URL 那样工作。在元数据重要的地方使用 long 值的 length API,并根据实际要求的长度或校验和验证已完成的产物。读取正文并不会让先前不存在的头部出现。

相关文章