在我基于 Java/Dropwizard 的应用程序中,我有一个端点允许客户端根据请求下载他们的数据。客户端使用 Curl/Wget 等工具调用端点。此端点按需构建 ZIP 存档,并使用 ZipOutputStream 将其流式传输回客户端。在内部,端点知道它必须处理多少数据,并且能够相当准确地预测进度。但是,由于使用 ZIP,显然不能在响应头中设置诸如 Content-Length 之类的内容。数据量可能很大,客户提示下载时间估计不足。
curl <endpoint> > foo.zip
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 7466k 0 7466k 0 0 10351 0 --:--:-- 0:12:18 --:--:-- 8985
想知道是否有一种方法可以通过标准 HTTP 方法将进度传达给客户端?
最佳答案
你真的应该在发送之前压缩存档。 Content-Length header 对于任何不使用分块传输编码的 HTTP 事务都是必不可少的……如果您使用的是 Java,我猜您没有使用分块传输编码(我承认我可能是错的)。
无法向客户端更新下载进度。我知道这听起来并不令人满意,所以我将解释原因。发送 header 并且客户端开始读取 HTTP 消息正文后,收到的所有数据都将被视为消息正文。您发送到该客户端套接字的任何内容都与压缩存档的字节没有区别。不可能发送任何将被 curl 或 wget 解释为元数据的内容。
您真正应该发送内容长度的另一个原因是 curl 和 wget 不知道消息何时结束(再次假设您没有使用分块传输编码)。即使您关闭了 OutputStream,curl 和 wget 也会继续监听更多数据,直到它们超时,这可能需要长达 15 秒的不活动时间。
如果您只是事先压缩文件并发送内容长度,一切都会自行处理。 curl 和 wget 都会自动监控和显示进度,并在收到所有数据后停止监听连接。
关于java - 根据客户要求流式传输大型存档文件的进展情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34448670/