6

我正在将客户端构建到 RESTful API 上。一些链接让我可以从服务器下载附件(文件),最好是 .txt。我只提到了 RESTful 部分,因为这意味着我必须在每篇文章中发送一些标题和可能的正文——标准的 R 'filename'=URL 逻辑不起作用。

有时人们将许多 txt 文件捆绑到一个 zip 文件中。这些很尴尬,因为我不知道它们包含什么,直到我下载了很多。

目前,我正在解压缩这些文件,压缩文件(添加 .gz 扩展名)并重新上传它们。然后可以对它们进行索引和下载。

我正在使用 Hadley 的可爱httr包,但我看不到解压缩 gz 文件的优雅方法。

使用 read.csv 或类似文件时,任何以 gz 结尾的文件都会自动解压缩(方便!)。使用 httr 或 curl 时的等价物是什么?

content(GET("http://glimmer.rstudio.com/alexbbrown/gz/sample.txt.gz"))
[1] 1f 8b 08 08 4e 9e 9b 51 00 03 73 ...

看起来不错,带有正确标头 (1f 8b) 的压缩字节流。现在我需要文本内容,所以我尝试使用 memDecompress,它说它应该这样做:

memDecompress(content(GET("http://glimmer.rstudio.com/alexbbrown/gz/sample.txt.gz")),type="gzip")
Error in memDecompress(content(GET("http://glimmer.rstudio.com/alexbbrown/gz/sample.txt.gz")),  : 
  internal error -3 in memDecompress(2)

这里的正确解决方案是什么?

另外,有没有办法让 R 提取远程 .zip 文件的索引而不下载所有文件?

4

2 回答 2

5

以下工作,但似乎有点令人费解:

> scan(gzcon(rawConnection(content(GET("http://glimmer.rstudio.com/alexbbrown/gz/sample.txt.gz")))),"",,,"\n")
Read 1 item
[1] "These are not the droids you are looking for"
于 2013-05-21T16:43:34.367 回答
3

您可以添加一个解析器来处理 mime 类型。看?content和线You can add new parsers by adding appropriately functions to httr:::parser

ls(httr:::parsers)

#[1] "application/json"                  "application/x-www-form-urlencoded" #"image/jpeg"                       
#[4] "image/png"                         "text/html"                         #"text/plain"                       
#[7] "text/xml"     

我们可以添加一个来处理gz内容。在这一点上,我没有比您给出的更好的答案,因此您可以合并您的功能。

assign("application/octet-stream", function(x, ...) {scan(gzcon(rawConnection(x)),"",,,"\n")},envir = httr:::parsers)

content(GET("http://glimmer.rstudio.com/alexbbrown/gz/sample.txt.gz"), as = "parsed")

Read 1 item
[1] "These are not the droids you are looking for"
> 

编辑:我一起破解了一个替代方案:

assign("application/octet-stream", function(x, ...) {f <- tempfile(); writeBin(x,f);untar(f);readLines(f, warn = FALSE)},envir = httr:::parsers)

content(GET("http://glimmer.rstudio.com/alexbbrown/gz/sample.txt.gz"), as = "parsed")
#[1] "These are not the droids you are looking for"

关于列出存档中的文件,您可能可以稍微调整一下功能。如果我们尝试获取httr源文件。他们有一个 mime 类型“application/x-gzip”

assign("application/x-gzip", function(x, ...) {
    f <- tempfile(); 
    writeBin(x,f); 
    if(!is.null(list(...)$list)){
        if(list(...)$list){
            return(untar(f, list = TRUE))
        }else{
            untar(f, ...);
            readLines(f)
        }
    }else{
        untar(f, ...);
        readLines(f)
    }
}, envir = httr:::parsers)

content(GET("http://cran.r-project.org/src/contrib/httr_0.2.tar.gz"), as = "parsed", list = TRUE)

# > head(content(GET("http://cran.r-project.org/src/contrib/httr_0.2.tar.gz"), as = "parsed", list = TRUE))
#[1] "httr/"                 "httr/MD5"              "httr/tests/"          
#[4] "httr/tests/test-all.R" "httr/README.md"        "httr/R/"
于 2013-05-21T17:44:36.087 回答