Я думаю, вы хотите использовать 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);
а в R в конце ?curlPerform есть пример вызова функции 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
который в линуксе создает файл curl_writer.so, а потом в R
dyn.load("curl_writer.so")
writer <- getNativeSymbolInfo("writer", PACKAGE="curl_writer")$address
curlPerform(URL=url, writefunction=writer)
и получить на stderr
<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 кажется псевдонимом функции записи) отправляет указатель на файл функции, ожидающей указатель на что-то еще; для getURL необходимо предоставить как данные записи, так и запись.
person
Martin Morgan
schedule
17.03.2013