私はあなたが使いたいと思い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
プロトタイプを持つ C 関数へのポインターである curl オプション CURL_WRITEFUNCTION があること
size_t function(void *ptr, size_t size, size_t nmemb, void *stream);
また、R では ?curlPerform の最後に「writefunction」オプションとして C 関数を呼び出す例があります。だから私はファイル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)
stderrに乗る
<writer> size = 1, nmemb = 2653
<writer> size = 1, nmemb = 520
OK
これら 2 つのアイデアは統合できます。つまり、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 によって作成されたようなファイル ハンドルではなく、RCurl によって管理されるバッファに書き込むことだと思いますCFILE
。同様に、writedata
withoutを指定するとwrite
(ソース コードから getURL への書き込み関数のエイリアスのように見えます)、ファイルへのポインターが別の何かへのポインターを期待する関数に送信されます。getURL には、writedata と write の両方を指定する必要があります。