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、またはzipまたはrarをダウンロードした場合、またはテキスト以外のファイルをダウンロードした場合、ダウンロード後に開くことができません(無効なファイルを言います)。

何が欠けているのかわかりません。助けていただければ幸いです。

これが非効率的なコーディング方法であることは知っていますが、ダウンロードが正しくなければなりません(任意のファイル)。効率性に取り組むことが私の次の議題です。

PS:ここで使用されているこの方法を使用 しましたC++でlibcurlを使用して複数のファイルをダウンロードします

ありがとうございました

4

3 に答える 3

1

ダウンロード時のファイルはバイナリファイルとして開く必要があります

fp = fopen(ofname,"wb");

助けてくれてありがとうロブ

于 2012-08-24T15:46:46.153 に答える
0

これは推測です。:オプションCURLOPT_TRANSFERTEXTとをクリアしてみてくださいCURLOPT_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
}

ビビアン・ロボの内容を一気に見られるように表現しました。私はビビアン・ロボの発言をテストしようとしました。うまくいっています。

stackOverFlowはコードを書くのが難しいです。そして、どうすればビビアンロボの記事にコメントできますか?

于 2013-11-15T01:44:07.870 に答える