2

我已使用以下代码从 FTP 服务器下载所有文件

步骤如下: 1. 创建文件的 FTP 列表

    getFTPList(string sHost, string sUser, string sPass, string sUri)
{
  CURL *curl;
  CURLcode res;
  FILE *ftplister;
  string host = "ftp://";
  host += sHost;
  host += "/sample/";
  string furl = host + sUri;  
  string usrpwd = sUser;
  usrpwd += ":";
  usrpwd += sPass;
  /* local file name to store the file as */ 
  ftplister = fopen("ftp-list", "wb"); /* b is binary, needed on win32 */   
  curl = curl_easy_init();
  if(curl) {
    /* Get a file listing from sunet */ 
    curl_easy_setopt(curl, CURLOPT_URL, furl.c_str() );
    curl_easy_setopt(curl, CURLOPT_USERPWD, usrpwd.c_str());
    curl_easy_setopt(curl, CURLOPT_FTPLISTONLY, TRUE);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_list);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftplister);
    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(ftplister); /* close the local file */   
}
  1. 使用此列表以递归方式下载调用下载函数的文件

    int main(){
    FILE *ftpfile; 
    string line;
    ftpfile = fopen("ftp-list", "r"); 
    ifstream infile("ftp-list");
     while ( getline(infile, line) )
     {
        string url, ofname, surl = "ftp://myhost/uploader/", sfname = "C:\\CNAP\\";        
        url = surl + line;
        ofname = sfname +line;
        cout<<url<<"   "<<ofname<<endl;
        char* theVal ;
        char* theStr ;
        theVal = new char [url.size()+1];
        theStr = new char [ofname.size()+1];
        strcpy(theVal, url.c_str());
        strcpy(theStr, ofname.c_str());       
        downloadFile(theVal, theStr);
     }
    return 0;
    }
    

现在下载功能:

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
    size_t written;
    written = fwrite(ptr, size, nmemb, stream);
    return written;
   }

   void downloadFile(const char* url, const char* ofname)
   {
    CURL *curl;
        FILE *fp;
        CURLcode res;        
        curl = curl_easy_init();
        if (curl){
            fp = fopen(ofname,"wb");
            curl_easy_setopt(curl, CURLOPT_URL, url);
            curl_easy_setopt(curl, CURLOPT_USERPWD, "user:pass");
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
            res = curl_easy_perform(curl);
            curl_easy_cleanup(curl);
            fclose(fp);
        }
     }

它在实现时效果很好,但只能下载文本文件或一些带有文本的文件,如果我下载图像或 docx 或 aa zip 或 rar 或任何非文本文件失败,下载后无法打开(说无效文件)。

我不确定我错过了什么,任何帮助将不胜感激。

我知道这是一种低效的编码方式,但我只需要正确的下载(任何文件)。提高效率是我的下一个议程。

PS:使用这里使用的这种方法 在 C++ 中使用 libcurl 下载多个文件

谢谢

4

3 回答 3

1

下载时的文件需要打开为二进制文件

fp = fopen(ofname,"wb");

谢谢你的帮助罗

于 2012-08-24T15:46:46.153 回答
0

这是一个猜测。:尝试清除选项CURLOPT_TRANSFERTEXTCURLOPT_CRLF

参考:

于 2012-08-24T13:29:44.467 回答
0
#include <stdio.h> 
#include <curl/curl.h>
#include <curl/easy.h>
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream);

void getFileList(
    const string &strHost, 
    const string &strUri, 
    const string &strUser, 
    const string &strPassWord, 
    const string &strTargetFile
);

void downloadAllFiles(
    const string &strFtpListFile, 
    const string &strHost, 
    const string &strUri, 
    const string &strUser, 
    const string &strPassWord, 
    const string &strSaveTargetFolder
);



int main(void) 
{
    string strHost = "ftp://192.168.0.1:22";
    string strUri = "/cobus/test/";
    string strUser = "cobus";
    string strPassWord = "password";
    string strTargetFile = "c:\\cobus\\ftpList.txt";
    string strSaveDestFolder = "c:\\cobus\\";

    getFileList(strHost, strUri, strUser, strPassWord, strTargetFile);

    downloadAllFiles(
        strTargetFile, 
        strHost, 
        strUri, 
        strUser, 
        strPassWord, 
        strSaveDestFolder
    );
}

size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) 
{
    size_t written = fwrite(ptr, size, nmemb, stream);
    return written;

}


void getFileList(const string &strHost, const string &strUri, 
const string &strUser, const string &strPassWord, const string &strTargetFile)
{
    CURL *curl;
    CURLcode res;
    FILE *ftplister;
    string strSourceFullUri = strHost + strUri;
    string strUserPwInfo = strUser + ":" + strPassWord;

    /* local file name to store the file as */ 
    ftplister = fopen(strTargetFile.c_str(), "wb"); /* b is binary, needed on win32 */

    curl = curl_easy_init();

    if(curl) 
    {
        /* Get a file listing from sunet */ 
        curl_easy_setopt(curl, CURLOPT_URL, strSourceFullUri.c_str() );
        curl_easy_setopt(curl, CURLOPT_USERPWD, strUserPwInfo.c_str());
        curl_easy_setopt(curl, CURLOPT_FTPLISTONLY, TRUE);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftplister);
        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(ftplister); /* close the local file */   

}

void downloadAllFiles(const string &strFtpListFile, const string &strHost, 
    const string &strUri, const string &strUser, const string &strPassWord, 
    const string &strSaveDestFolder)
{
    FILE *ftpFile = NULL;
    string strFileName = "";

    ifstream infile(strFtpListFile.c_str());

    if(!infile.is_open())
    {
        cerr << "can not open ftpList.txt" << endl;
        return ;
    }

    /* ftpList.txt get data, line by line, processing */
    while(getline(infile, strFileName))
    {
        CURL *curl;
        FILE *destFilePath;
        CURLcode res;        

        curl = curl_easy_init();

        if (curl)
        {
            destFilePath = fopen((strSaveDestFolder+strFileName).c_str(),"wb");
            curl_easy_setopt(curl, CURLOPT_URL, (strHost+strUri+strFileName).c_str());
            curl_easy_setopt(curl, CURLOPT_USERPWD, (strUser+":"+strPassWord).c_str());
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, destFilePath);
            res = curl_easy_perform(curl);

            curl_easy_cleanup(curl);

            fclose(destFilePath);
        }
    }// end while
}

我表示尽可能地立即看到 Vivian Lobo 的内容。我试图测试做出陈述 Vivian Lobo。这是很好的工作。

stackOverFlow 很难写代码。我如何评论 Vivian lobo 文章?

于 2013-11-15T01:44:07.870 回答