简体   繁体   English

在R中下载文件时捕获FTP日志

[英]Capture the FTP log when downloading a file in R

I want to download a file via ftp, and also capture the ftp log. 我想通过ftp下载文件,并且还捕获ftp日志。 I managed to get this far: 我设法做到了这一点:

options(internet.info = 0)  # displays the ftp log in the console

x <- capture.output(
  download.file("ftp://speedtest.tele2.net/1KB.zip", destfile = tempfile()),
  type = "message"
)

This displays the ftp log in the console and captures some download.file() output to the variable x , but it does not capture the ftp log. 这将在控制台中显示ftp日志,并捕获一些输出到变量x download.file() ,但不会捕获ftp日志。 I also tried some fiddling around with sink() , but no success. 我也尝试了一下sink() ,但没有成功。

Can anyone explain to me why this is not working, and is there any way to achieve what I want? 谁能向我解释为什么这行不通,并且有什么方法可以实现我想要的? I want to process some ftp messages so simply getting back an error code would not suffice. 我想处理一些ftp消息,因此仅获取错误代码是不够的。

If you're using Linux or Cygwin or Git bash, you can pipe the results of a script to a text file. 如果您使用的是Linux或Cygwin或Git bash,则可以将脚本结果通过管道传输到文本文件。 If you put your code (without the output capturing) into a file called script.R you can pipe all the output to a text file: 如果将代码(不捕获输出)放入名为script.R的文件中,则可以将所有输出传递给文本文件:

Rscript script.R &> script.txt

You can do something like this within R - but it feels evil to me: 您可以在R中执行类似的操作-但对我来说,这很邪恶:

uri <- "ftp://speedtest.tele2.net/1KB.zip"
destination <- tempfile()

system2("Rscript", 
        c("-e", 
          sprintf("\"options(internet.info = 0);download.file('%s', destfile = '%s', quiet = FALSE)\"", 
                  uri, 
                  destination)), 
        stderr = TRUE, stdout = TRUE)

With the help of sebastian-c and the original package author I was able to devise a solution for my problem with the curl package. 在sebastian-c和原始软件包作者的帮助下,我能够为curl软件包的问题设计解决方案。 I'll try to preserve it here for posterity: 我将在这里保留它以供后代使用:

curl_download_with_log <- function(
  url,
  destfile
){
  log <- rawConnection(raw(), 'r+')
  on.exit(close(log))
  stopifnot(is.character(url))

  h <- curl::new_handle(
    debugfunction = function(type, data){
      if(type %in% c(0, 1, 2)){ 
        writeBin(data, log)
      }
    },
    verbose = TRUE
  )

  try({
    curl::curl_download(url, destfile = destfile, handle = h)
  })

  rawToChar(rawConnectionValue(log))
}

This function will save the file to destfile , and return the log as a character vector. 此函数会将文件保存到destfile ,并将日志作为字符向量返回。

Explaination: 阐释:

  • debugfunction tells libcurl what to do with the debugging data. debugfunction告诉libcurl如何处理调试数据。 In this case, write it to a binary connection 在这种情况下,将其写入二进制连接

  • if(type %in% c(0, 1, 2)){...} ensures that only log data is written to the debug connection. if(type %in% c(0, 1, 2)){...}确保仅将日志数据写入调试连接。 If you leave this out, the whole file you download gets written to the debug log along with the protocol data (see link for explaination of the different debug levels) 如果您不进行此操作,则下载的整个文件将与协议数据一起写入调试日志(请参阅链接以获取有关不同调试级别的说明)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM