如何在Ruby下载之前获取远程文件的mtime?

时间:2009-10-02 11:49:56

标签: ruby http file download

我有以下代码,只需下载文件并保存即可。我想每隔30秒运行一次并检查远程文件的mtime是否已更改,如果有,则将其下载。 为了这个目的,我将创建一个在无限循环的每次迭代后休眠30秒的线程,但是;如何在不下载的情况下检查远程文件的mtime?

Net::HTTP.start($xmlServerHostname) { |http|
                resp = http.get($xmlServerPath+"levels.xml")
                open("levels.xml", "w") { |file|
                    file.write(resp.body)
                }
            }

3 个答案:

答案 0 :(得分:8)

在执行http.get之前,执行http.head只请求标题而不下载正文(即文件内容),然后检查Last Modified标头的值是否已更改。

e.g。

resp = http.head(($xmlServerPath+"levels.xml")
last_modified = resp['last-modified']
if last_modified != previous_last_modified
  # file has changed
end

答案 1 :(得分:3)

您可以尝试使用格式正确的日期发送If-Modified-Since标题。

如果服务器支持它,它只能以304 Not Modified状态(没有任何内容)回答,或者如果文件被修改则可以回答全部内容。

答案 2 :(得分:0)

official Net::HTTP 2.6.5 docshttps://stackoverflow.com/a/1509202/895245

提到的If-Modified-Since的具体示例。
uri = URI('http://example.com/cached_response')
file = File.stat 'cached_response'

req = Net::HTTP::Get.new(uri)
req['If-Modified-Since'] = file.mtime.rfc2822

res = Net::HTTP.start(uri.hostname, uri.port) {|http|
  http.request(req)
}

open 'cached_response', 'w' do |io|
  io.write res.body
end if res.is_a?(Net::HTTPSuccess)

这是一个实际运行的完整脚本:

#!/usr/bin/env ruby

require 'net/http'
require 'time'

uri = URI('https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Illumina_iSeq_100_flow_cell_top.jpg/451px-Illumina_iSeq_100_flow_cell_top.jpg')
file_path = 'cached_response'
req = Net::HTTP::Get.new(uri)
if File.file?(file_path)
  req['If-Modified-Since'] = File.stat(file_path).mtime.rfc2822
end
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) {|http|
  http.request(req)
}
if res.is_a? Net::HTTPSuccess
  File.open(file_path, 'w') {|io|
    io.write res.body
  }
end

但是TODO每次都会更新文件,即使Wikimedia似乎会解释If-Modified-Sincehttps://wikitech.wikimedia.org/wiki/MediaWiki_caching