java - 根据客户要求流式传输大型存档文件的进展情况?

标签 java http streaming dropwizard

在我基于 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/

相关文章:

http - SecureSocket 支持哪些协议(protocol)?

javascript - Node JS 匿名函数和回调

python 请求非 ascii 数据的问题

performance - 在空间使用量恒定的情况下从磁盘流式传输数据的最有效的习惯用法是什么?

java - 替换序列化数据中的类名

java - 如何在运行时使用javac编译器设置类路径?

java - 如何使用 java String.replaceAll(string regex,string replacement) 来得到我想要的?

streaming - RTSP 1.0 与 RTSP 2.0

streaming - Hadoop 流作业失败 : Task process exit with nonzero status of 137

java - 我应该将接口(interface)声明为返回值还是将实现声明为返回值?