我想你想使用writedata 并记得关闭文件
library(RCurl)
filename <- tempfile()
f <- CFILE(filename, "wb")
url <- "http://cran.fhcrc.org/Rlogo.jpg"
curlPerform(url = url, writedata = f@ref)
close(f)
对于更详细的写作,我不确定这是否是最好的方式,但 Linux 告诉我,来自
man curl_easy_setopt
有一个 curl 选项 CURL_WRITEFUNCTION,它是一个指向带有原型的 C 函数的指针
size_t function(void *ptr, size_t size, size_t nmemb, void *stream);
在 ?curlPerform 末尾的 R 中有一个调用 C 函数作为“writefunction”选项的示例。所以我创建了一个文件 curl_writer.c
#include <stdio.h>
size_t
writer(void *buffer, size_t size, size_t nmemb, void *stream)
{
fprintf(stderr, "<writer> size = %d, nmemb = %d\n",
(int) size, (int) nmemb);
return size * nmemb;
}
编译好了
R CMD SHLIB curl_writer.c
在 Linux 上产生一个文件 curl_writer.so,然后在 R
dyn.load("curl_writer.so")
writer <- getNativeSymbolInfo("writer", PACKAGE="curl_writer")$address
curlPerform(URL=url, writefunction=writer)
进入标准错误
<writer> size = 1, nmemb = 2653
<writer> size = 1, nmemb = 520
OK
这两个想法可以整合,即使用任意函数写入任意文件,通过修改C函数使用我们传入的FILE *,如
#include <stdio.h>
size_t
writer(void *buffer, size_t size, size_t nmemb, void *stream)
{
FILE *fout = (FILE *) stream;
fprintf(fout, "<writer> size = %d, nmemb = %d\n",
(int) size, (int) nmemb);
fflush(fout);
return size * nmemb;
}
编译后返回R中
dyn.load("curl_writer.so")
writer <- getNativeSymbolInfo("writer", PACKAGE="curl_writer")$address
f <- CFILE(filename <- tempfile(), "wb")
curlPerform(URL=url, writedata=f@ref, writefunction=writer)
close(f)
getURL也可以在这里使用,前提是writedata=f@ref, write=writer;我认为原始问题中的问题是R_curl_write_binary_data 确实是一个内部函数,写入由 RCurl 管理的缓冲区,而不是像CFILE 创建的文件句柄。同样,指定 writedata 而不指定 write (从源代码看来 getURL 是 writefunction 的别名)将指向文件的指针发送到期望指向其他指针的函数;对于 getURL,writedata 和 write 都需要提供。