微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有向下宝石的 Ruby 进度条

如何解决带有向下宝石的 Ruby 进度条

我正在使用 down gem 实现文件下载器。

我需要在我的程序中添加一个进度条以获得精美的输出。我发现了一颗名为 ruby-progressbar 的宝石。但是,即使我遵循了官方网站上记录的说明,我也无法将其集成到我的代码库中。这是我到目前为止所做的:

首先,我想到了使用 progress_proc。这是一个坏主意,因为 progress_proc 返回分块的部分数据。

其次,我 streamed 数据并构建了计算分块数据的想法。它实际上运行良好,但对我来说闻起来很糟糕。

另外,这是我的代码库的一小部分。我希望它能帮助你理解这个概念。

progressbar = ProgressBar.create(title: 'File 1')
Down.download(url,progress_proc: ->(progress) { progressbar.progress = progress }) # It doesn't work
progressbar = ProgressBar.create(title: 'File 1')
file = Down.open(url,progress_proc: ->(progress) { progressbar.progress = progress })
chunked = 0
loop do
  break if file.eof?

  file.read(1024)
  chunked += 1024

  progressbar.progress = (chunked / file.size) * 100
end

# This worked well as I remember. It can be faulty because I wrote it down without testing.

解决方法

在 HTTP 协议中,客户端如何确定响应的全长有两种不同的方式:

  1. 在最常见的情况下,整个响应由服务器一次性发送。此处,响应正文的长度(以字节为单位)在响应的 Content-Length 标头中设置。因此,如果响应没有分块,您可以获取此标头的值并在服务器发送响应时一次性读取响应。
  2. 第二个选项是服务器发送分块响应。在这里,服务器一个接一个地发送整个响应的块。每个块都以块的长度为前缀。但是,客户端无法知道总共有多少块,也无法知道总响应有多大。通常,这对服务器来说甚至是未知的,因为在服务器可以使用整个响应之前,第一个块已经发送。

down gem 通过提供两个接口来遵循这两种方法:

在第一种情况下(即如果整个响应的内容长度已知),gem 将调用给定的 content_length_proc 一次。

在第二种情况下,由于响应的整个长度在收到之前是未知的,因此 down gem 为收到的每个块调用一次 progress_proc。在这种情况下,您可以展示一些有用的东西。通常,您不能在此处将进度条显示为完成百分比。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。