如何计算Ruby中下载的数据量和要下载的总数据量

如何计算Ruby中下载的数据量和要下载的总数据量,ruby,Ruby,我正在尝试构建一个桌面客户端,用Ruby管理一些下载。我想知道如何着手确定下载了多少数据以及要下载的整个数据的大小 我正试图用Ruby来做这件事,所以任何帮助都是有用的 提前感谢。正如韦恩在评论中所说,这取决于用于传输文件的协议。以HTTP为例,HTTP响应将包括一个Content-Length头,它将告诉您正在下载的文件的长度。在您知道之后,您必须跟踪从HTTP连接读取的字节数 这样的方式似乎很管用(适用于HTTP),但如果可以更优雅地执行,我也不会感到惊讶: require 'net/htt

我正在尝试构建一个桌面客户端,用Ruby管理一些下载。我想知道如何着手确定下载了多少数据以及要下载的整个数据的大小

我正试图用Ruby来做这件事,所以任何帮助都是有用的


提前感谢。

正如韦恩在评论中所说,这取决于用于传输文件的协议。以HTTP为例,HTTP响应将包括一个Content-Length头,它将告诉您正在下载的文件的长度。在您知道之后,您必须跟踪从HTTP连接读取的字节数

这样的方式似乎很管用(适用于HTTP),但如果可以更优雅地执行,我也不会感到惊讶:

require 'net/http' 

url = URI.parse('http://www.google.com/index.html')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) do |http|
  http.request(req) do |res|
    remaining = res.content_length
    puts "total length: #{remaining}"
    res.read_body do |segment|
      puts "read #{segment.length} bytes"
      remaining = remaining - segment.length
      puts "#{remaining} bytes remaining"
    end
  end
end

www.google.com/index.html是一个不好的例子,因为内容在一个片段中返回,但是在一个较大的对象上尝试它,你会看到多个“read…”行。

正如韦恩在评论中所说,这取决于用于传输文件的协议。以HTTP为例,HTTP响应将包括一个Content-Length头,它将告诉您正在下载的文件的长度。在您知道之后,您必须跟踪从HTTP连接读取的字节数

这样的方式似乎很管用(适用于HTTP),但如果可以更优雅地执行,我也不会感到惊讶:

require 'net/http' 

url = URI.parse('http://www.google.com/index.html')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) do |http|
  http.request(req) do |res|
    remaining = res.content_length
    puts "total length: #{remaining}"
    res.read_body do |segment|
      puts "read #{segment.length} bytes"
      remaining = remaining - segment.length
      puts "#{remaining} bytes remaining"
    end
  end
end

www.google.com/index.html是一个不好的例子,因为内容在一个片段中返回,但是在一个较大的对象上尝试它,您会看到多个“read…”行。

如果您使用的是Net::HTTP,那么您请求的内容的长度应该在响应头中。Net::HTTP mixin Net::HTTPHeader,在其中可以找到content_length()。尽管只有在传输发生之前确定大小时,它才起作用

HTTPResponse有一个方法可以分块读取正文,因此您可以使用它来确定进度。从0开始,添加每个块的长度,将其与总大小进行比较,就完成了

http.request_get('/index.html') {|res|
res.read_body do |segment|
  print segment
end
} #Example taken from Ruby-Documentation
如果您正在使用FTP,那么通过NET::FTP应该会更容易。连接到服务器,使用size(filename)获取给定文件的大小,然后使用get、getbinaryfile或gettextfile下载该文件

这是get方法的签名:get(remotefile,localfile=File.basename(remotefile),blocksize=DEFAULT_blocksize){| data |……}

ftp.get('file.something', 'file.something.local', 1024){ |data|
     puts "Downloaded 1024 more bytes"
}

如果您使用的是Net::HTTP,那么您请求的内容的长度应该在响应头中。Net::HTTP mixin Net::HTTPHeader,在其中可以找到content_length()。尽管只有在传输发生之前确定大小时,它才起作用

HTTPResponse有一个方法可以分块读取正文,因此您可以使用它来确定进度。从0开始,添加每个块的长度,将其与总大小进行比较,就完成了

http.request_get('/index.html') {|res|
res.read_body do |segment|
  print segment
end
} #Example taken from Ruby-Documentation
如果您正在使用FTP,那么通过NET::FTP应该会更容易。连接到服务器,使用size(filename)获取给定文件的大小,然后使用get、getbinaryfile或gettextfile下载该文件

这是get方法的签名:get(remotefile,localfile=File.basename(remotefile),blocksize=DEFAULT_blocksize){| data |……}

ftp.get('file.something', 'file.something.local', 1024){ |data|
     puts "Downloaded 1024 more bytes"
}

你是如何传送文件的?(ftp、ssh、telnet、自定义tcp/ip协议等)?您是否使用gem或其他库代码进行传输?大多数情况下,您会得到一个内容长度头,但有时它不会被返回。如果服务器或服务器调用的CGI无法预先确定返回数据的大小,那么您将一无所获。所以,用一种能够正确处理这种情况的方式编写代码。你是如何传输文件的?(ftp、ssh、telnet、自定义tcp/ip协议等)?您是否使用gem或其他库代码进行传输?大多数情况下,您会得到一个内容长度头,但有时它不会被返回。如果服务器或服务器调用的CGI无法预先确定返回数据的大小,那么您将一无所获。所以,编写代码的方式要能正确处理这种情况。你不能指望有一个内容长度的标题。如果CGI返回内容,他们可能没有实现它,如果内容是动态的,服务器可能无法确定实际大小。你不能指望有一个内容长度头。如果CGI返回内容,他们可能没有实现它,如果内容是动态的,服务器可能无法确定实际大小。