Загрузка libcurl ftp очень медленная - PullRequest
1 голос
/ 05 августа 2020

Я пишу программу на C ++, которая загружает каталоги с тысячами небольших файлов в них. Я использую библиотеку libcurl для загрузки, но она очень медленная. Я попробовал загрузить каталог с 1500 файлами. Моя программа тратит полчаса, а ftp mput - всего две минуты. Код следующий. Как сделать мою программу такой же быстрой, как ftp mput?

#include <stdio.h>
#include <string>
#include <string.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#include <dirent.h>
#endif

int main(int ac, char *av[])
{
    if (ac != 3) {
        return 1;
    }

    std::string ip = av[1];
    std::string local_path = av[2];
    if (local_path[local_path.size() - 1] == '/')
    {
        local_path = local_path.substr(0, local_path.size() - 1);
    }

    std::string folder;
    std::size_t found = local_path.rfind("/");
    if (found != std::string::npos) {
        folder = local_path.substr(found + 1);
    }
    else {
        folder = local_path;
    }

    struct dirent *dirst;
    DIR *dp = opendir(local_path.c_str());
    while ((dirst = readdir(dp)) != NULL)
    {
        std::string name = dirst->d_name;
        if (name == "." || name == "..")
        {
            continue;
        }

        std::string url;
        url += "ftp://" + ip + "/" + folder + "/" + name;
        printf("%s\n", url.c_str());
        std::string file = local_path + "/" + name;

        CURL *curl;
        CURLcode res;
        FILE *hd_src;
        struct stat file_info;
        curl_off_t fsize;

        /* get a FILE * of the same file */
        hd_src = fopen(file.c_str(), "rb");

        /* In windows, this will init the winsock stuff */
        curl_global_init(CURL_GLOBAL_ALL);

        /* get a curl handle */
        curl = curl_easy_init();
        if (curl) {

            /* enable uploading */
            curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

            /* specify target */
            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

            curl_easy_setopt(curl, CURLOPT_USERPWD, "ingest:upload");

            /* now specify which file to upload */
            curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);

            curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);

            /* Now run off and do what you've been told! */
            res = curl_easy_perform(curl);
            /* Check for errors */
            if (res != CURLE_OK)
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));

            /* always cleanup */
            curl_easy_cleanup(curl);
        }
        fclose(hd_src); /* close the local file */

        curl_global_cleanup();

    }

    closedir(dp);
    return 0;
}
...