• 使用C++实现功能下载文件


           今天问一个同学C++实现的下载链接下载并保存给定的文件,互联网搜索。看到这样的事情在网上。因此,改变下直接带来,因为他的代码是在VC++,我导入到VS2010中出现点小问题。所以改了下贴了个VS中亲測可执行的代码。在此记录下。

    參考的资料   http://bbs.csdn.net/topics/390052882   感觉里面大家讨论的都不错

    事实上这个使用到MFC中的一些函数。能够做成图形界面的。

    以下贴下自己小小改动的代码

    //#define _WIN32_WINNT 0x0502
    #include <afx.h>
    #include <afxinet.h>
    #include <iostream>
    using namespace std;
    #define RECVPACK_SIZE 2048
    bool DownloadSaveFiles(const char* url,const char* strSaveFile) {//下载文件并保存为新文件名称
        bool ret=false;
        CInternetSession Sess(_T("lpload"));
        Sess.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT     , 5000); //5秒的连接超时
        Sess.SetOption(INTERNET_OPTION_SEND_TIMEOUT        , 5000); //5秒的发送超时
        Sess.SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT     , 5000); //5秒的接收超时
        Sess.SetOption(INTERNET_OPTION_DATA_SEND_TIMEOUT   , 5000); //5秒的发送超时
        Sess.SetOption(INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, 5000); //5秒的接收超时
        DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ;
    
        CHttpFile* cFile   = NULL;
        char      *pBuf    = NULL;
        int        nBufLen = 0   ;
        do {
            try{
                cFile = (CHttpFile*)Sess.OpenURL((CString)url,1,dwFlag);
                DWORD dwStatusCode;
                cFile->QueryInfoStatusCode(dwStatusCode);
                if (dwStatusCode == HTTP_STATUS_OK) {
                    //查询文件长度
                    DWORD nLen=0;
                    cFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, nLen);
                    //CString strFilename = GetFileName(url,TRUE);
                    nBufLen=nLen;
    				//cout << "nLen=" << nLen << endl;
                    if (nLen <= 0) break;//
    
                    //分配接收数据缓存
                    pBuf = (char*)malloc(nLen+8);
                    ZeroMemory(pBuf,nLen+8);
    
                    char *p=pBuf;
                    while (nLen>0) {
                        //每次下载8K
                        int n = cFile->Read(p,(nLen<RECVPACK_SIZE)?nLen:RECVPACK_SIZE);
                        //接收完毕退出循环
                        if (n <= 0) break;//
                        //接收缓存后移
                        p+= n ;
                        //剩余长度递减
                        nLen -= n ;
    					//cout << "nLen=" << nLen << endl;
                    }
    
                    //假设未接收完中断退出
                    if (nLen != 0) break;
    
                    //接收成功保存到文件
    
                    CFile file((CString)strSaveFile, CFile::modeCreate | CFile::modeWrite);
                    file.Write(pBuf,nBufLen);
                    file.Close();
                    ret = true;
                }
            } catch(...) {
    			cout << "异常" << endl;
                break;//
            }
        } while(0);
    
        //释放缓存
        if (pBuf) {
            free(pBuf);
            pBuf=NULL;
            nBufLen = 0 ;
        }
    
        //关闭下载连接
        if (cFile) {
            cFile->Close();
            Sess.Close();
            delete cFile;
        }
        return ret;
    }
    int main() {
    	//測试用例
        if(DownloadSaveFiles("http://www.nirsoft.net/utils/nircmd.zip","d:/cppdld_nircmd.zip") == true)
    	{
    		cout << "下载成功" << endl;
    	}else{
    		cout << "下载失败"<< endl;
    	}
        return 0;
    }

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Bootstrap3.0学习第八轮(工具Class)
    dependencies与dependencyManagement的区别
    灵活控制 Hibernate 的日志或 SQL 输出,以便于诊断
    Linux平台安装MongoDB
    ubuntu 该软件包现在的状态极为不妥 error
    oracle vm突然黑屏了
    Oracle VM VirtualBox各种显示模式切换 热键
    where后一个条件和多个条件的查询速度
    String特殊值的判断方式
    将中文标点符号替换成英文标点符号
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4811028.html
Copyright © 2020-2023  润新知