zoukankan      html  css  js  c++  java
  • C++ 解析XML下载类

    调用迅雷的接口,封装一个自己的类。

    工程下载地址: http://pan.baidu.com/share/link?shareid=208860&uk=3037189616

    迅雷下载库的网址:http://thunderplatform.xunlei.com

    // FileName: Download.h
    #pragma once
    #include "lib\XLDownload.h"
    #include "lib\XLError.h"
    #include <vector>
    
    // 下载队列的大小,决定同时开启下载线程的数量
    const int LIMIT = 2;
    
    struct Down
    {
        // 解析出来的下载地址
        CString strDownURL;
        // 保存的路径
        CString strSavePath;
    };
    
    struct Flag
    {
        DWORD dwFlag;            // 记录下载线程实时状态
        LONG lTaskId;            // 记录对应任务ID号
        ULONGLONG ullFileSize;    // 下载文件大小
        ULONGLONG ullRecvSize;    // 已下载大小
    };
    
    class CDownload
    {
    private:
        
        // 保存下载的日志信息
        std::vector<CString> strLogArr;
    
        // 解析XML文件
        //void Analysis (LPCTSTR lpPathXML, LPCTSTR lpBegin, LPCTSTR lpEnd);
        void Analysis (LPCTSTR lpPathXML);
        
        // 开始下载
        void Start (void);
    
        // 调用迅雷的下载接口
        void CreateDownThread (int n);
    
        // 下载任务查询监控线程
        static void DownQury (LPVOID ptr);
    
        // 保存日志
        void SaveLog (LPCTSTR lpPathAndName);
    
    public:
    
        // 保存解析出来的下载队列
        std::vector<Down> strDownArr;
    
        // 记录最新的下载位置
        int m_nIndex;
    
        // 下载队列的大小,对应位为1时,该下载位为空,可以启动新的下载线程
        struct Flag Flags[LIMIT];
    
        // 总共的下载数
        int m_nTotal;
    
        // 失败的下载数
        int m_nFail;
    
        // 成功的下载数
        int m_nSuccess;
    
        CDownload();
        ~CDownload();
        BOOL DownloadFilesByXML(LPCTSTR lpPahtXML);
    };
    // FileName: Download.cpp
    #include "stdafx.h"
    #include "Download.h"
    #include <Shlwapi.h>
    #include <locale.h>
    #pragma comment(lib, "lib\\XLDownload.lib")
    
    // 包含XTP界面库头文件
    #include "XTToolkitPro.h"
    
    CDownload::CDownload()
    {
        // 初始化
        m_nIndex = 0;
    
        // 初始化为没有下载线程
        for (int n=0; n<LIMIT; n++)
        {
            Flags[n].dwFlag = 1;
            Flags[n].lTaskId = n;
        }
    
        m_nSuccess = 0;
        m_nTotal = 0;
        m_nFail = 0;
    }
    
    CDownload::~CDownload()
    {
    
    }
    
    BOOL CDownload::DownloadFilesByXML(LPCTSTR lpPathXML)
    {
        DWORD dwRet = XL_SUCCESS;
    
        // 检测XML文件是否存在
        if (!PathFileExists(lpPathXML))
        {
            ::MessageBox(NULL, _T("XML文件不存在!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION);    
            return FALSE;
        }
    
        // 解析XML文件
        Analysis(lpPathXML);
        
        // 统计下载链接数
        m_nTotal = strDownArr.size();
    
        // 开始下载
        Start();
    
        return TRUE;
    }
    
    //void CDownload::Analysis(LPCTSTR lpPathXML, LPCTSTR lpBegin, LPCTSTR lpEnd)
    void CDownload::Analysis(LPCTSTR lpPathXML)
    {
        // 读取XML文件
        CXTPPropExchangeXMLNode px(TRUE, NULL, _T("DownLoadInfo"));
    
        if (!px.LoadFromFile(lpPathXML))
        {
    
            ::MessageBox(NULL, _T("打开XML文件出错!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION);
            return;
        }
    
        if (!px.OnBeforeExchange())
        {
            ::MessageBox(NULL, _T("OnBeforeExchange false!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION);
            return;
        }
    
        px.SetCompactMode(TRUE);
    
        CXTPPropExchangeEnumeratorPtr enumItem(px.GetEnumerator(_T("Item")));
        POSITION posItem = enumItem->GetPosition();
    
        CString strLocalName;
        Down down;
    
        // 遍历所有的结点
        while (posItem)
        {
            CXTPPropExchangeSection sec(enumItem->GetNext(posItem));
    
            if (sec->IsLoading())
            {
                PX_String(sec->GetSection(_T("URL")), NULL, down.strDownURL);
                PX_String(sec->GetSection(_T("LocalPath")), NULL, down.strSavePath);
                PX_String(sec->GetSection(_T("LocalName")), NULL, strLocalName);
    
                down.strSavePath += strLocalName;
                // 路径转换
                down.strSavePath.Replace('/', '\\');
    
                strDownArr.push_back(down);
            }
        }
    }
    
    // 下载任务查询
    void CDownload::DownQury (LPVOID ptr)
    {
        CDownload* pDown = (CDownload*)ptr;
        bool nSign = true;
        DWORD dwRst;
        TCHAR errorBuf[500];
        DWORD dwSize = 500;
        CString strLog;
    
        // 如果没有下载完成一直下载
        while ((pDown->m_nIndex < (pDown->strDownArr).size()) || nSign)
        {
            int n = 0;
            LONG temp = -1;
            nSign = false;
    
            while (n<LIMIT)
            {
                switch(pDown->Flags[n].dwFlag)
                {
                    // 没有下载,开始新的下载
                    case 1 : 
                        pDown->CreateDownThread(n);
                        dwRst = XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize));
                        
                        if (dwRst == XL_SUCCESS && pDown->m_nIndex<pDown->strDownArr.size())
                        {
                            pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL);
                            pDown->strLogArr.push_back(_T("state:suceess"));
                            pDown->Flags[n].dwFlag = temp;
                        }
                        else 
                        {
                            if (pDown->m_nIndex < pDown->strDownArr.size())
                            {
                                pDown->m_nFail += 1;
                                XLGetErrorMsg(dwRst, errorBuf, dwSize);
                                pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL);
                                strLog.Format(_T("state:%s"), errorBuf);
                                pDown->strLogArr.push_back(strLog);
                            }
                            pDown->m_nIndex += 1;
                        }
                        break;
    
                    // 成功下载完, 开始新的下载
                    case 11: 
                        pDown->CreateDownThread(n); 
                        dwRst = XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize));
                        if (dwRst == XL_SUCCESS && pDown->m_nIndex<pDown->strDownArr.size())
                        {
                            pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL);
                            pDown->strLogArr.push_back(_T("state:suceess"));
                            pDown->Flags[n].dwFlag = temp;
                        }
                        else 
                        {
                            if (pDown->m_nIndex < pDown->strDownArr.size())
                            {
                                pDown->m_nFail += 1;
                                XLGetErrorMsg(dwRst, errorBuf, dwSize);
                                pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL);
                                strLog.Format(_T("state:%s"), errorBuf);
                                pDown->strLogArr.push_back(strLog);
                            }
                            pDown->m_nIndex += 1;
                        }
                        break;
                    
                    // 下载失败,开始新的下载
                    case 12: 
                        pDown->CreateDownThread(n);
                        dwRst = XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize));
                        if (dwRst == XL_SUCCESS && pDown->m_nIndex<pDown->strDownArr.size())
                        {
                            pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL);
                            pDown->strLogArr.push_back(_T("state:suceess"));
                            pDown->Flags[n].dwFlag = temp;
                        }
                        else 
                        {
                            if (pDown->m_nIndex < pDown->strDownArr.size())
                            {
                                pDown->m_nFail += 1;
                                XLGetErrorMsg(dwRst, errorBuf, dwSize);
                                pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL);
                                strLog.Format(_T("state:%s"), errorBuf);
                                pDown->strLogArr.push_back(strLog);
                            }
                            pDown->m_nIndex += 1;
                        }
                        break;
                    
                    // 默认处理
                    default:
                        XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize));
                        pDown->Flags[n].dwFlag = temp;
                        if (temp == enumTaskStatus_Download)
                        {
                            nSign = true;
                        }
                }
                n++;
            }
            //Sleep(1);
        }
    
        // 保存日志
        pDown->SaveLog(_T("C:\\down.log"));
    
        CString strTemp;
        strTemp.Format(_T("下载完成! 下载总数:%d 成功总数%d 失败总数%d 日志存在位置:C:\\down.log"), pDown->m_nTotal, pDown->m_nSuccess, pDown->m_nFail);
        ::MessageBox(NULL, strTemp, _T("友情提示"), MB_OK);
        
        pDown->m_nSuccess = 0;
        pDown->m_nTotal = 0;
        pDown->m_nFail = 0;
    
        // 恢复初始状态
        pDown->m_nIndex = 0;
    
        // 恢复为下载队列为空
        for (int n=0; n<LIMIT; n++)
        {
            pDown->Flags[n].dwFlag = 1;
            pDown->Flags[n].lTaskId = n;
            // 无论是否下载成功,都必须调用XLStopTask
            XLStopTask(pDown->Flags[n].lTaskId);
        }
    
        //释放资源
        XLUninitDownloadEngine();
    }
    
    void CDownload::Start (void)
    {
        int nIndex = 0;
    
        // 1、初始化下载引擎
        if ( FALSE == XLInitDownloadEngine() )
        {
            ::MessageBox(NULL, _T("初始化下载引擎失败!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION);
            return;
        }
    
        // 下载任务查询监控线程
        ::CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)DownQury, this, 0, NULL);
    }
    
    // 调用迅雷的下载接口
    void CDownload::CreateDownThread (int n)
    {
        DWORD dwRst = 0;
        if (m_nIndex < strDownArr.size())
        {
            dwRst = XLURLDownloadToFile(strDownArr[m_nIndex].strSavePath, strDownArr[m_nIndex].strDownURL, NULL, Flags[n].lTaskId);
            if (dwRst == XL_SUCCESS)
            {
                Flags[n].dwFlag = enumTaskStatus_Download;
                m_nIndex++;
                m_nSuccess++;
            }
        }
        else
        {
            m_nIndex = strDownArr.size();
        }
    }
    
    void CDownload::SaveLog (LPCTSTR lpPathAndName)
    {
        CStdioFile file;
        std::vector<CString>::iterator iter;
    
        // 保存现在的语言环境
        char * old_locale = _strdup(setlocale(LC_CTYPE,NULL));
        // 设置中文环境
        setlocale(LC_CTYPE, "chs");
    
        if (file.Open(lpPathAndName, CFile::modeCreate|CFile::modeWrite))
        {
            for (iter=strLogArr.begin(); iter!=strLogArr.end(); iter++)
            {
                file.WriteString(*iter);
                file.WriteString(_T("\n"));
            }
        }
        file.Close();
        // 还原语言区域的设置 
        setlocale(LC_CTYPE, old_locale);
        //  释放内存
        free(old_locale);
    }
  • 相关阅读:
    清单
    1
    s
    模块系统的演进
    改radio样式
    前端css库
    疑惑
    收藏
    事件
    社保档案
  • 原文地址:https://www.cnblogs.com/calm2012/p/2866624.html
Copyright © 2011-2022 走看看