我正在尝试使用download.file
下载以下数据集,该数据集只适用于method = "wget"
)
# Doesn't work
download.file('http://uofi.box.com/shared/static/bba3968d7c3397c024ec.dta', tempfile(), method = "auto")
download.file('http://uofi.box.com/shared/static/bba3968d7c3397c024ec.dta', tempfile(), method = "curl")
# Works
download.file('http://uofi.box.com/shared/static/bba3968d7c3397c024ec.dta', tempfile(), method = "wget")
根据help(download.file)
,
如果选择method =“auto”(默认值),则内部方法为 为file:// URL和其他提供的URL选择 功能(“http / ftp”)是真的(几乎总是如此)。
查看源代码,“内部方法”是指:
if (method == "internal") {
status <- .External(C_download, url, destfile, quiet,
mode, cacheOK)
if (!quiet)
flush.console()
}
但是,我仍然不知道.External(C_download)
做了什么,特别是跨平台。对我来说,了解这一点并不依赖于wget
非常重要,因为我正在撰写一个应该跨平台工作的软件包。
答案 0 :(得分:3)
此源代码位于R源代码中(从http://cran.r-project.org/sources.html下载当前版本)。相关代码(自R 3.2.1起)位于&#34; ./ src / modules / internet / internet.c&#34;和&#34; ./ src / modules / internet / nanohttp.c&#34;。
根据后者,极简主义HTTP GET功能的代码基于libxml2-2.3.6。
如果您不想下载整个.tgz文件并将其解压缩,则可以在R {s}网站https://svn.r-project.org/R/branches/R-3-2-branch/src/modules/internet/internet.c和https://svn.r-project.org/R/branches/R-3-2-branch/src/modules/internet/nanohttp.c上找到这些文件。
如果查看代码,大多数代码在不同平台上都是一致的。但是,在Windows上,似乎使用了wininet代码。
最初在utils
包中查找代码,因为这是找到R命令download.file
的地方。我grep
可以在&#34; ./ src / library / utils / src&#34;中的c文件中下载。目录,发现相关代码在&#34; sock.c&#34;。该文件中有一条评论高达/* from src/main/internet.c */
所以我接下来去了#34; internet.c&#34;。
对于您的特定文件,问题是您所拥有的链接会返回302 Found
状态代码。在Windows上并使用wget,下载例程遵循302响应的Location
字段并获取实际文件。使用curl方法有效但仅当您提供参数extra="-L"
。
download.file('http://uofi.box.com/shared/static/bba3968d7c3397c024ec.dta', tempfile(), method = "curl", extra="-L")
有一个名为downloader
的软件包声称可以为https提供良好的跨平台解决方案。给定一个http URL,它只是将调用传递给download.file
。这是一个适用于http的版本。它也默认为二进制传输,这似乎是一个好主意。
my_download <- function(url, destfile, method, quiet = FALSE,
mode = "wb", cacheOK = TRUE, extra = getOption("download.file.extra")) {
if (.Platform$OS.type == "windows" && (missing(method) || method %in% c("auto", "internal", "wininet"))) {
seti2 <- utils::"setInternet2"
internet2_start <- seti2(NA)
on.exit(suppressWarnings(seti2(internet2_start)))
suppressWarnings(seti2(TRUE))
} else {
if (missing(method)) {
if (nzchar(Sys.which("wget")[1])) {
method <- "wget"
} else if (nzchar(Sys.which("curl")[1])) {
method <- "curl"
if (!grepl("-L", extra)) {
extra <- paste("-L", extra)
}
} else if (nzchar(Sys.which("lynx")[1])) {
method <- "lynx"
} else {
stop("no download method found")
}
}
}
download.file(url = url, destfile = destfile, method = method, quiet = quiet, mode = mode,
cacheOK = cacheOK, extra = extra)
}
答案 1 :(得分:0)
你可以自己回答这个问题。只需在控制台提示符下键入download.file
,您就会在函数定义的顶部看到它:
if (method == "auto") { # this is actually the default from
# getOption("download.file.method", default = "auto")
if (capabilities("http/ftp"))
method <- "internal"
else if (length(grep("^file:", url))) {
method <- "internal"
url <- URLdecode(url)
}
else if (system("wget --help > /dev/null") == 0L)
method <- "wget"
else if (system("curl --help > /dev/null") == 0L)
method <- "curl"
else if (system("lynx -help > /dev/null") == 0L)
method <- "lynx"
else stop("no download method found")
}
if (method == "internal") {
status <- .External(C_download, url, destfile, quiet,
mode, cacheOK)
if (!quiet)
flush.console()
}