【问题标题】:How to keep downloaded file (from FTP) timestamp with R?如何使用 R 保存下载的文件(来自 FTP)时间戳?
【发布时间】:2016-09-15 14:16:56
【问题描述】:

我目前正在尝试通过 FTP(使用 R)下载文件,但我想保留源时间戳(上次修改日期)。

我知道 download.file(来自 {base} R)可以与一些附加功能一起使用,我在网上看到 -R--remote-time 应该可以解决问题。但是我写的代码确实将修改后的日期作为下载的日期(和时间)。

download.file(url = "ftp://ftp.datasus.gov.br/dissemin/publicos/SIASUS/200801_/Dados/ABAC1502.dbc",
          destfile = "C:/LocalPath/ABAC1502.dbc",
          quiet = T,
          mode = 'wb',
          method = "libcurl",
          extra = "--remote-time")

我错过了什么吗?

我也在其他的FTP服务器上尝试过,没有成功。

更多详情:RStudio v0.99.484、R v3.3.1 (x64)、操作系统 Windows 7 Enterprise SP1

【问题讨论】:

  • 试试method="curl" vs method="libcurl"
  • @hrbrmstr 更改为 method="curl" 会引发两个错误:错误 127下载非零退出状态
  • 我认为这意味着 curl 二进制文件不在系统 PATH 上,这并不奇怪,因为它是 Windows 并且不太可能安装。

标签: r download ftp


【解决方案1】:

更新

我知道它必须被内置,并发现它与 utils::file.… 操作完全分开在 base::Sys… 操作中:

Sys.setFileTime(path, time)

¯\_(ツ)_/¯

尽管如此,为什么没有将其扩展为分别启用actime(访问时间)和modtime(修改时间)的设置,我无法理解。 访问 明确表示上次检查文件内容的时间。 修改表示文件内容被更改的时间(从系统调用的角度来看,每个文件的构成都有 POSIX 规则。

我觉得有必要用更权威的解决方案来更新答案(尽管我的解决方案更符合 POSIX 定义的精神,尽管没有使用utimensat——这在大多数系统上都不可用)。请记住,使用内置解决方案,您正在破坏访问和修改而不是仅仅修改。


我无法加载该网站,我认为您的问题可以通过在extra 中从libcurl 切换到curl 解决,但这是一个更通用的解决方案(在 macOS 和 Windows 上测试)我用一个已知的工作 FTP 站点进行了测试:

library(curl)
library(Rcpp)
library(inline)

h <- new_handle()
handle_setopt(h, filetime=TRUE, verbose=TRUE) # verbose is just for my debugging
h <- curl_fetch_disk("ftp://ftp.ngdc.noaa.gov/STP/SOLAR_DATA/AIRGLOW/IGYDATA/abst5270",
                      "abst5270", h)

h$modified
## [1] "1999-10-22 18:59:10 EDT"

as.numeric(h$modified)
## [1] 940633150

set_modtime <- rcpp(sig=c(path="character", ts="integer"), body=
" struct stat f_stat;
  struct utimbuf ftp_time;
  std::string file_path = as<std::string>(path);
  long file_ts = as<long>(ts);
  if (stat(file_path.c_str(), &f_stat) >= 0) {
    ftp_time.actime = f_stat.st_atime;
    ftp_time.modtime = file_ts;
    utime(file_path.c_str(), &ftp_time);
  }
", includes=c("#include <time.h>", "#include <utime.h>", "#include <sys/stat.h>"))

# Changes it to way back in the past
invisible(set_modtime("abst5270", as.numeric(h$modified)))

# Changes it back to right now
invisible(set_modtime("abst5270", as.numeric(Sys.time())))

它需要在包中进行一些额外的检查和异常处理,但这在脚本中可以正常工作。

请注意,您必须使用完整路径或可访问的工作相对路径(这可能很明显,但我想确保它已得到解释)。

【讨论】:

  • 像魅力一样工作。非常好的解决方案,非常感谢!
【解决方案2】:

另外,检查http://github.com/ajdamico/lodown/ 中的datasus 函数。可能有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    相关资源
    最近更新 更多