国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于curl 使用http多線程下載大文件

這篇具有很好參考價(jià)值的文章主要介紹了基于curl 使用http多線程下載大文件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、獲取文件大小

int64_t CHttpClient::GetFileSize(const std::string &url)
{
    auto curl = curl_easy_init();
    if (!curl)
    {
        curl_easy_cleanup(curl);
        return -1;
    }
    double filesize = -1; //文件大小

    curl_easy_setopt(curl,CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADER, 1); 
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1); 
    CURLcode res_code = curl_easy_perform(curl); //請(qǐng)求
    if (res_code != CURLE_OK)
    {
        curl_easy_cleanup(curl);
        return -1;
    }
    
    curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize); 
    curl_easy_cleanup(curl);

    std::cout << "獲取文件大小完成:" << (int64_t)filesize  << std::endl;
    return filesize;
}

二、劃分線程

    auto client = GetClient();
    auto length = client->GetFileSize(url);
//根據(jù)線程數(shù)劃分塊大小
    auto blockSize = length / thNum;
    auto lastBlock = (length % thNum == 0 ? blockSize : blockSize + length % thNum );
    
    //啟動(dòng)多個(gè)線程進(jìn)行下載
    std::vector<std::future<bool>> vecFt;
    std::vector<std::shared_ptr<INetProtocol>> vecDownload;
    for (size_t i = 0; i < thNum; i++)
    {
        auto block = (i == thNum - 1 ? lastBlock : blockSize);
        auto dlClient = GetClient();
        vecDownload.push_back(dlClient);
        vecFt.emplace_back(std::async(std::bind(&INetProtocol::Download, dlClient, url, blockSize * i,  block)));
    }

三、下載區(qū)間數(shù)據(jù)

bool CHttpClient::Download(const std::string &url, int64_t offset, int64_t blocksize)
{
    auto curl = curl_easy_init();
    if (!curl)
    {
        curl_easy_cleanup(curl);
        return false;
    }
    auto rangeEnd = offset + blocksize - 1;
    std::cout << "開(kāi)始下載數(shù)據(jù),區(qū)間:" << offset << "-" <<  rangeEnd  << ",塊大小:" << blocksize << std::endl;
	m_blockData = std::make_shared<BlockData>(offset, blocksize);
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 10);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CHttpClient::WriteBlock);
    std::stringstream ss;
    ss << offset << "-" << rangeEnd;
	curl_easy_setopt(curl, CURLOPT_RANGE, ss.str().c_str());
	CURLcode res_code = curl_easy_perform(curl);
    if (res_code != CURLE_OK)
    {
        curl_easy_cleanup(curl);
        return false;
    }
	std::cout << "下載數(shù)據(jù):" << offset << "-" << rangeEnd << ", 獲取數(shù)據(jù):" << m_blockData->readSize << "完成" << std::endl;
	curl_easy_cleanup(curl);
    return true;
}

四、等待所有線程完成

//同步等待所有線程完成
    bool isFaild = false;
    for (auto i = 0; i < vecFt.size(); i++)
	{
        if (!vecFt[i].get())
        {
            isFaild = true;
            std::cout << "線程:" << i << "下載失敗" << std::endl;
        }       
    }

五、合并線程數(shù)據(jù)

void CDownload::MergerData(const std::string &fileName, std::vector<std::shared_ptr<INetProtocol>>& vecDownload)
{
    std::ofstream fout(fileName, std::ios::out | std::ios::binary);
	if (!fout)
	{
        throw std::runtime_error("create local file faild");
	}
    for (auto& item : vecDownload)
    {
        fout << item->GetStream().rdbuf();
    }
    
}

6、獲取服務(wù)器文件MD5

std::string CHttpClient::GetContextMd5(const std::string &url)
{
    auto curl = curl_easy_init();
    if (!curl)
    {
        curl_easy_cleanup(curl);
        return std::string();
    }


    curl_easy_setopt(curl,CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HEADER, 1); 
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1); 

    std::string strMd5;
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &strMd5);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, CHttpClient::ReadHeader);
    CURLcode res_code = curl_easy_perform(curl); //請(qǐng)求
    if (res_code != CURLE_OK)
    {
        curl_easy_cleanup(curl);
        return std::string();
    }
    
    curl_easy_cleanup(curl);
    std::cout << "獲取Md5完成:" << strMd5  << std::endl;
    return strMd5;
}

7、檢驗(yàn)文件MD5是否一致

bool CDownload::CheckFile(const std::string &url, const std::string& strLocalFile)
{
    auto client = GetClient();
    auto contextMd5 = client->GetContextMd5(url);
    auto localMd5 = GetContentMd5(strLocalFile);
    std::cout << "context    md5:" << contextMd5 << std::endl;
    std::cout << "local file md5:" << localMd5  << std::endl;
    if (contextMd5 != localMd5)
    {
        std::cout << "md5 校驗(yàn)失敗, 文件下載失敗" << std::endl;
        return false;
    }
    std::cout << "md5 校驗(yàn)一致, 文件下載成功" << std::endl;
    return true;
}


//獲取本地文件MD5,然后通過(guò)Base64編碼輸出
std::string CDownload::GetContentMd5(const std::string &fileName)
{
    std::ifstream fin(fileName, std::ios::in  | std::ios::binary);
    if (!fin)
    {
        throw std::runtime_error("獲取文件MD5失敗,文件打開(kāi)失敗");
    }

    EVP_MD_CTX  *mdctx;
    unsigned char *md5_digest;
    unsigned int md5_digest_len = EVP_MD_size(EVP_md5());

    mdctx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);

    const int bufSize = 4 * 1024 * 1024;
    char *pszBuf = new char[bufSize];
    while (!fin.eof())
    {
        fin.read(pszBuf, bufSize);
        EVP_DigestUpdate(mdctx, pszBuf, fin.gcount());
    }
    md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len);
    EVP_DigestFinal_ex(mdctx, md5_digest, &md5_digest_len);
    EVP_MD_CTX_free(mdctx);
    delete[] pszBuf;
    return CBase64::encode(std::string((char*)md5_digest, md5_digest_len));
}

如需完整代碼,可評(píng)論區(qū)留言文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-756313.html

到了這里,關(guān)于基于curl 使用http多線程下載大文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • http 協(xié)議大文件下載

    http 協(xié)議大文件下載

    ? ? ? ? http 協(xié)議的響應(yīng)報(bào)文格式包括起始行+頭部字段+響應(yīng)正文,其格式為: ????????響應(yīng)的正文只能通過(guò)http響應(yīng)消息進(jìn)行傳輸,如果是小文件(比如小于1M)傳輸,則沒(méi)有什么問(wèn)題,直接把文件內(nèi)容加載到正文進(jìn)行回應(yīng)即可,但如果是大文件(比如大于10M),不可能把

    2024年02月09日
    瀏覽(18)
  • 網(wǎng)絡(luò):如何使用curl命令測(cè)試HTTP代理的有效性

    網(wǎng)絡(luò):如何使用curl命令測(cè)試HTTP代理的有效性

    在我們的日常工作中,代理服務(wù)器扮演著重要的角色,它幫助我們?cè)L問(wèn)局部網(wǎng)絡(luò)無(wú)法直接訪問(wèn)的資源。然而,代理的設(shè)置和驗(yàn)證有時(shí)候會(huì)比較復(fù)雜。幸運(yùn)的是,作為一名開(kāi)發(fā)者應(yīng)該熟悉curl,一個(gè)強(qiáng)大的工具來(lái)測(cè)試和驗(yàn)證代理服務(wù)器的設(shè)置。本文將引導(dǎo)我們?nèi)绾问褂胏url命令測(cè)

    2024年04月22日
    瀏覽(29)
  • Web服務(wù)器實(shí)現(xiàn)|基于阻塞隊(duì)列線程池的Http服務(wù)器|線程控制|Http協(xié)議

    Web服務(wù)器實(shí)現(xiàn)|基于阻塞隊(duì)列線程池的Http服務(wù)器|線程控制|Http協(xié)議

    代碼地址:WebServer_GitHub_Addr 摘要 本實(shí)驗(yàn)通過(guò)C++語(yǔ)言,實(shí)現(xiàn)了一個(gè)基于阻塞隊(duì)列線程池的多線程Web服務(wù)器。該服務(wù)器支持通過(guò)http協(xié)議發(fā)送報(bào)文,跨主機(jī)抓取服務(wù)器上特定資源。與此同時(shí),該Web服務(wù)器后臺(tái)通過(guò)C++語(yǔ)言,通過(guò)原生系統(tǒng)線程調(diào)用 pthread.h ,實(shí)現(xiàn)了一個(gè) 基于阻塞隊(duì)列

    2024年02月07日
    瀏覽(21)
  • linux下下載文件的常用命令wget,curl等使用方法及使用示例

    linux下下載文件的常用命令wget,curl等使用方法及使用示例

    在 Linux 操作系統(tǒng)中,有許多下載文件的工具可供選擇。這些工具包括命令行工具和圖形界面工具,每個(gè)工具都有其自身的特點(diǎn)和用途。以下是一些常用的下載文件工具: wget :一個(gè)功能強(qiáng)大的命令行下載工具,支持 HTTP、HTTPS、FTP 等協(xié)議,能夠斷點(diǎn)續(xù)傳、遞歸下載等。 curl :

    2024年04月17日
    瀏覽(56)
  • Golang中基于HTTP協(xié)議的網(wǎng)絡(luò)服務(wù)

    HTTP協(xié)議是基于TCP/IP協(xié)議棧的,并且它也是一個(gè)面向普通文本的協(xié)議。 只要搞清楚了HTTP請(qǐng)求的報(bào)文(報(bào)文的頭部(header)和主體(body))應(yīng)該包含的內(nèi)容,使用任何一個(gè)文本編譯器,就餓可以編寫(xiě)一個(gè)完整的HTTP請(qǐng)求報(bào)文。 在這種情況下,直接使用 net.Dial 函數(shù),就可以。 使

    2023年04月09日
    瀏覽(87)
  • java通過(guò)http網(wǎng)絡(luò)url下載文件

    上面代碼報(bào)錯(cuò),修改 URL url = new URL(fileUrl); ,使用 URL url = new URL(new URI(fileUrl).toASCIIString()); 原因: URL url = new URL(fileUrl); 和 URL url = new URL(new URI(fileUrl).toASCIIString()); 之間有一些微小的區(qū)別。 URL url = new URL(fileUrl);:這種方式直接使用 URL 類的構(gòu)造函數(shù)創(chuàng)建一個(gè) URL 對(duì)象。它假設(shè)

    2024年02月12日
    瀏覽(91)
  • 基于 HTTP Range 實(shí)現(xiàn)文件分片并發(fā)下載!

    基于 HTTP Range 實(shí)現(xiàn)文件分片并發(fā)下載!

    目錄 前言 基礎(chǔ)下載功能 進(jìn)階下載功能 單片下載 多片下載? 瀏覽器發(fā)送預(yù)檢(preflight)請(qǐng)求 express 不支持多段 range multipart/** 搭配 boundary=** 分片下載功能 “只讀的” ArrayBuffer 對(duì)象 DataView 子類?Uint8Array?操作二進(jìn)制數(shù)據(jù) Blob + createObjectURL 創(chuàng)建 url 全部代碼 通用的文件分片下載

    2024年02月10日
    瀏覽(20)
  • python基于http的網(wǎng)絡(luò)通信和網(wǎng)站端口暴露;Python網(wǎng)絡(luò)編程之HTTP協(xié)議的python應(yīng)用

    HTTP(Hypertext Transfer Protocol)即超文本傳輸協(xié)議,是Web應(yīng)用程序使用的協(xié)議,在Web瀏覽器和Web服務(wù)器之間傳遞HTML頁(yè)面和數(shù)據(jù)。HTTP是基于TCP/IP協(xié)議來(lái)傳輸數(shù)據(jù)的,是一種無(wú)狀態(tài)的協(xié)議。 關(guān)鍵特點(diǎn): 支持客戶/服務(wù)器模式:Web瀏覽器作為HTTP客戶端通過(guò)URL向HTTP服務(wù)器發(fā)送HTTP請(qǐng)求,

    2024年02月04日
    瀏覽(28)
  • Java基于ftp協(xié)議實(shí)現(xiàn)文件的上傳和下載

    Java基于ftp協(xié)議實(shí)現(xiàn)文件的上傳和下載

    相比其他協(xié)議,如 HTTP 協(xié)議,F(xiàn)TP 協(xié)議要復(fù)雜一些。與一般的 C/S 應(yīng)用不同點(diǎn)在于一般的C/S 應(yīng)用程序一般只會(huì)建立一個(gè) Socket 連接,這個(gè)連接同時(shí)處理服務(wù)器端和客戶端的連接命令和數(shù)據(jù)傳輸。而FTP協(xié)議中將命令與數(shù)據(jù)分開(kāi)傳送的方法提高了效率。 FTP 使用 2 個(gè)端口,一個(gè)數(shù)據(jù)

    2024年02月11日
    瀏覽(29)
  • Linux curl 命令下載文件

    Linux curl 命令下載文件

    ? 在Linux中curl是一個(gè)利用URL規(guī)則在命令行下工作的文件傳輸工具,可以說(shuō)是一款很強(qiáng)大的http命令行工具。它支持文件的上傳和下載,是綜合傳輸工具,但按傳統(tǒng),習(xí)慣稱curl為下載工具。 語(yǔ)法: 常見(jiàn)參數(shù): 1、基本用法 執(zhí)行后,www.linux.com 的html就會(huì)顯示在屏幕上了 Ps:由于

    2024年02月15日
    瀏覽(27)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包