我有一个存储250KB数据的char数组。我想使用libcurl将这个char数组上传到S3的存储桶中。我知道如何上传文件,并且可以将所有数据写入文件并将文件发送到S3,但这会增加不必要的额外步骤。

长话短说,如何使用libcurl上传内存的特定部分?

最佳答案

我终于找到了解决方案,并且无需使用中间文件就可以成功上传数据。

如果您未声明读取回调函数,则libcurl将使用fread,它要求您输入文件指针作为输入。我发现克服此指针问题的方法是编写一个读回调函数,然后输入void指针作为READDATA的输入。事不宜迟,这里是工作代码。另一个重要说明是您要上传的框架集的大小。

#include <stdio.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

int framesetSize = 10;
void *frameset = "0123456789";
static size_t my_read_callback(void *ptr, size_t size, size_t nmemb, void *dummy)
{
    // we will ignore dummy, and pass frameset as a global parameter, along with framesetSize
    size_t retcode = 0;

    if  (framesetSize == 0)
// we have already finished off all the data
        return retcode; // initialized to 0

    retcode =  ( size * nmemb >= framesetSize) ? framesetSize : size * nmemb;
// set return code as the smaller of max allowed data and remaining data

    framesetSize -=  retcode; // adjust left amount
    memcpy(ptr, frameset, retcode);
    frameset += retcode ; // advance frameset pointer
    return retcode;
}

int main(void)
{
    CURL *curl;
    CURLcode res;
    double speed_upload, total_time;

    curl = curl_easy_init();
    if(curl) {
        /* upload to this place */
        curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_callback);

        curl_easy_setopt(curl, CURLOPT_URL,
                         "54.231.19.24/{YOURBUCKETNAME}/furkan-1.txt");

        /* tell it to "upload" to the URL */
        curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

        /* set where to read from (on Windows you need to use READFUNCTION too) */
        curl_easy_setopt(curl, CURLOPT_READDATA, &frameset);

        /* and give the size of the upload (optional) */
        curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, framesetSize);

        /* enable verbose for easier tracing */
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

        res = curl_easy_perform(curl);
        /* Check for errors */
        if(res != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));

        }
        else {
            /* now extract transfer info */
            curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
            curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);

            fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
                    speed_upload, total_time);

        }
        /* always cleanup */
        curl_easy_cleanup(curl);
    }
    return 0;
}

07-25 23:00
查看更多