http - 如何在从 Racket 输入端口读取时显示 HTTP 文件下载进度

标签 http download progress-bar lisp racket

我的问题的根源是我需要能够获取已下载的总字节数以显示进度条作为 cli 工具的一部分。

我正在通过 HTTP GET 请求下载文件。使用“Content-Length”http header ,我可以看到我将使用我的客户端下载的文件的总大小。我想我会做旧的“下载/总计=进度”公式。

我当前的实现可以毫无问题地获取文件并将其写入本地文件系统,因此请求和端口的设置按预期工作,我真的只需要一些指导,了解如何深入了解输入端口是什么实际上在做(事件?)我对 Racket 很陌生。

我正在使用以下库来发出 http 请求:

https://docs.racket-lang.org/http/index.html?q=http

提到了有助于实现进度条的有用程序:

https://github.com/greghendershott/http/blob/master/http/request.rkt#L505

这是我目前所拥有的:

#| Basically just for debugging/testing, receives the default input-port 
#| and headers from the call/input-request procedure

(define (handle-entity in headers)
  (display headers)

  #| looking at the source this "read-entity/transfer-decoding-port" 
  #| should be useful for what I want to do
  (define decoded-port (read-entity/transfer-decoding-port in headers))

  #| writing the file works as expected, what I really want to do is
  #| is get the download progress as I write to the output-port
  (call-with-output-file "test.tar.gz"
                        (lambda (out)
                          (display (port->bytes decoded-port) out))))

(define (fetch)
  (call/input-request "1.1"
                      "GET"                       
                      "https://example.com/test.tar.gz"
                      empty
                      handle-entity #| will handle the input port created in this procedure
                      #:redirects 10))

最佳答案

您可以使用 port-progress-evt有效地等到端口被读取,你可以使用 port-next-location检查到目前为止已经读取了多少字节。您可以在另一个线程的循环中执行此操作以异步更新进度条。例如:

(define (listen-for-progress in)
  (sync (port-progress-evt in))
  (unless (port-closed? in)
    (define-values [line col pos] (port-next-location in))
    (printf "bytes read: ~a\n" pos)
    (listen-for-progress in)))

(define (read-with-progress in)
  (thread (λ () (listen-for-progress in)))
  #| do something with in |#)

顺便说一句,你应该使用 copy-port而不是 port->bytes 后跟 display,因为 copy-port 会将输入端口流式传输到输出端口,但是 port->bytes 将在开始写入输出端口之前将整个端口读入内存。

关于http - 如何在从 Racket 输入端口读取时显示 HTTP 文件下载进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50849325/

相关文章:

php - 没有数据库的 $_POST 和 $_GET 变量安全

facebook - 登录请求失败的正确 HTTP 状态代码是什么? (或者为什么 gmail/fb 响应新页面)

ajax - Extjs 4 通过ajax调用下载文件

android - 从 Android App 下载的文件在下载目录中不可见

C# WebClient 使用异步并返回数据

xml - 如何让服务器将内容类型设置为 text/xml

javascript - 在for循环中进行同步http调用

api - 我在哪里可以下载所有必要的类来编写 Hadoop MapReduce 作业?

flash - 更改 Flex 下载进度栏组件的栏颜色的简单方法?

java - 如何在操作栏中制作自定义进度条?