我的问题的根源是我需要能够获得已下载的总字节数,以显示进度条作为cli工具的一部分。
我通过HTTP GET请求下载文件。使用" Content-Length" http标题我可以看到我将用我的客户端下载文件的总大小。我想我会做旧的"下载/ total =进度" 公式。
我当前的实现可以获取文件并将其写入本地文件系统没有问题,因此请求和端口的设置按预期工作,我真的只需要一些指导如何了解输入端口是什么实际上做(事件?)我对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))
答案 0 :(得分:2)
您可以使用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
会在开始写入输出端口之前将整个端口读入内存。