#pragma once class CDownloadDlg; class CInternetDownload { public: typedef struct { DWORD nStart;//文件片段的起始位置 DWORD nEnd;//文件片段的长度 size_t nIndex;//当前线程的编号 size_t nTotal; CInternetDownload* pThis; } ThreadParam; CInternetDownload(CDownloadDlg* pDlg); virtual ~CInternetDownload(void); virtual int Download(const CString& strUrl, size_t nThreads); protected: static CString s_strUrl; static CDownloadDlg* s_pDlg; virtual DWORD GetFileLength(const CString& strUrl) = 0; virtual CFile* GetInternetFile(LPVOID) = 0; static UINT ServerWorkerThread(LPVOID lpParam); CInternetSession internetSession; private: CFile* m_internetFile; };
InternetDownload.cpp
#include "StdAfx.h" #include "./internetdownload.h" #include "DownloadDlg.h" CDownloadDlg* CInternetDownload::s_pDlg = NULL; CString CInternetDownload::s_strUrl; CInternetDownload::CInternetDownload(CDownloadDlg* pDlg) : m_internetFile(NULL) { s_pDlg = pDlg; } CInternetDownload::~CInternetDownload(void) { } UINT CInternetDownload::ServerWorkerThread(LPVOID lpParam) { ThreadParam *pParam = static_cast<ThreadParam *>(lpParam); CFile *pFile = pParam->pThis->GetInternetFile(lpParam); if (!pFile) return -1; CFile localFile; CString strFileName; strFileName.Format("c://temp.part%d", pParam->nIndex); if (!localFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite)) return -1; char * const pBuffer = new char[1024]; DWORD nLeft = pParam->nEnd - pParam->nStart + 1; while (TRUE) { int nRead = pFile->Read(pBuffer, nLeft > 1024 ? 1024 : nLeft); localFile.Write(pBuffer, nRead); if (nRead < 1024) break; nLeft -= nRead; } localFile.Close(); delete []pBuffer; pFile->Close(); delete pFile; s_pDlg->PostMessage(WM_DOWNLOADED_MESSAGE, pParam->nTotal, pParam->nIndex); delete pParam; pParam = NULL; return 0; } int CInternetDownload::Download(const CString& strUrl, size_t nThreads) { s_strUrl = strUrl; DWORD nFileSize = GetFileLength(strUrl); UINT nSegmentLength = (nFileSize + nThreads - 1) / nThreads; for (size_t i = 0; i < nThreads; i++) { ThreadParam *lpParam = new ThreadParam; //memset(lpParam, '/0', sizeof(ThreadParam)); lpParam->nTotal = nThreads; lpParam->nIndex = i; lpParam->nStart = nSegmentLength * i; lpParam->nEnd = lpParam->nStart + nSegmentLength - 1; lpParam->pThis = this; if (lpParam->nEnd >= nFileSize) lpParam->nEnd = nFileSize - 1; AfxBeginThread(ServerWorkerThread, static_cast<LPVOID>(lpParam), THREAD_PRIORITY_NORMAL, 0, 0, NULL); //CreateThread(NULL, 0, ServerWorkerThread, (LPVOID)i, 0, 0); } return 0; } #pragma once #include "InternetDownload.h" class CFtpDownload : public CInternetDownload { public: CFtpDownload(CDownloadDlg* pDlg); virtual ~CFtpDownload(void); // int Download(const CString& strUrl, size_t nThreads); private: DWORD GetFileLength(const CString& strUrl); CFile* GetInternetFile(LPVOID lpParam); };
#include "StdAfx.h" #include "./ftpdownload.h" #include "DownloadDlg.h" #include <winsock2.h> #include "shlwapi.h" #pragma comment(lib, "Wininet.lib") #pragma comment(lib, "shlwapi.lib") CFtpDownload::CFtpDownload(CDownloadDlg* pDlg) : CInternetDownload(pDlg) { // s_pDlg = pDlg; } CFtpDownload::~CFtpDownload(void) { } CFile* CFtpDownload::GetInternetFile(LPVOID lpParam) { ThreadParam *pParam = static_cast<ThreadParam *>(lpParam); CFtpConnection *pFtpConn = NULL; CString strServerName, strObject, strUserName, strPassword; DWORD dwServiceType; INTERNET_PORT nPort; if (!AfxParseURLEx(s_strUrl, dwServiceType, strServerName, strObject, nPort, strUserName, strPassword) || dwServiceType != INTERNET_SERVICE_FTP) { TRACE(_T("Not a ftp Quest! /n")); } pFtpConn = internetSession.GetFtpConnection(strServerName, strUserName, strPassword); CString strFtpCommand; strFtpCommand.Format("REST %d", pParam->nStart); if (!FtpCommand(*pFtpConn, FALSE, FTP_TRANSFER_TYPE_ASCII, strFtpCommand, 0, 0)) { int i = WSAGetLastError(); return NULL; } CFile *pFile = pFtpConn->OpenFile(strObject); return pFile; } /* int CFtpDownload::Download(const CString& strUrl, size_t nThreads) { DWORD nFileSize = GetFileLength(strUrl); s_strUrl = strUrl; UINT nSegmentLength = (nFileSize + nThreads - 1) / nThreads; for (size_t i = 0; i < nThreads; i++) { ThreadParam *lpParam = new ThreadParam; //memset(lpParam, '/0', sizeof(ThreadParam)); lpParam->nTotal = nThreads; lpParam->nIndex = i; lpParam->nStart = nSegmentLength * i; lpParam->nEnd = lpParam->nStart + nSegmentLength - 1; lpParam->pThis = this; if (lpParam->nEnd >= nFileSize) lpParam->nEnd = nFileSize - 1; AfxBeginThread(ServerWorkerThread, static_cast<LPVOID>(lpParam), THREAD_PRIORITY_NORMAL, 0, 0, NULL); //CreateThread(NULL, 0, ServerWorkerThread, (LPVOID)i, 0, 0); } return 0; } */ DWORD CFtpDownload::GetFileLength(const CString& strUrl) { CInternetSession internetSession; CFtpConnection *pFtpConn = NULL; CString strServerName, strObject, strUserName, strPassword; DWORD dwServiceType; INTERNET_PORT nPort; if (!AfxParseURLEx(strUrl, dwServiceType, strServerName, strObject, nPort, strUserName, strPassword) || dwServiceType != INTERNET_SERVICE_FTP) { TRACE(_T("Not a ftp Quest! /n")); return -1; } pFtpConn = internetSession.GetFtpConnection(strServerName, strUserName, strPassword); //FtpCommand("REST 1024"); /* if (!FtpCommand(*pFtpConn, FALSE, FTP_TRANSFER_TYPE_ASCII, "REST 1024", 0, 0)) return -1;*/ CInternetFile *pFile = pFtpConn->OpenFile(strObject); DWORD nFileSize = FtpGetFileSize(*pFile, 0); pFile->Close(); delete pFile; return nFileSize; }
#pragma once #include "InternetDownload.h" class CHttpDownload : public CInternetDownload { public: CHttpDownload(CDownloadDlg* pDlg); virtual ~CHttpDownload(void); private: // static UINT ServerWorkerThread(LPVOID lpParam); DWORD GetFileLength(const CString& strUrl); CFile* GetInternetFile(LPVOID lpParam); public: // int Download(const CString& strUrl, int nThreads); int FormatRequestHeader(void); }; #include "StdAfx.h" #include "./httpdownload.h" #include "DownloadDlg.h" static const char szHeaders[] = "Accept: */*/r/nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)/r/n"; CFile* CHttpDownload::GetInternetFile(LPVOID lpParam) { ThreadParam *pParam = static_cast<ThreadParam *>(lpParam); DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD; CString strHeader;//请求头 strHeader.Format("%sRange: bytes=%d-%d/r/n", szHeaders, pParam->nStart, pParam->nEnd);//pParam->nIndex * 8192);//, 1024 * 1024); return internetSession.OpenURL(s_strUrl, 1, dwFlag, strHeader, -1); } /* UINT CHttpDownload::ServerWorkerThread(LPVOID lpParam) { //size_t nIndex = reinterpret_cast<size_t>(lpParam);//第几个文件片段 ThreadParam *pParam = static_cast<ThreadParam *>(lpParam); char * const pBuffer = new char[1024]; //for (int i = 0; ; i++) while (TRUE) { int nRead = pHttpFile->Read(pBuffer, 1024); localFile.Write(pBuffer, nRead); if (nRead < 1024) break; } localFile.Close(); delete []pBuffer; pHttpFile->Close(); delete pHttpFile; s_pDlg->PostMessage(WM_DOWNLOADED_MESSAGE, pParam->nTotal, pParam->nIndex); delete pParam; return 0; } */ CHttpDownload::CHttpDownload(CDownloadDlg* pDlg) : CInternetDownload(pDlg) //: m_strHeader("Accept: */*/r/nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows XP)/r/n") { } CHttpDownload::~CHttpDownload(void) { } /* int CHttpDownload::Download(const CString& strUrl, int nThreads) { s_strUrl = strUrl; DWORD nFileSize = GetFileLength(strUrl); UINT nSegmentLength = (nFileSize + nThreads - 1) / nThreads; for (size_t i = 0; i < nThreads; i++) { ThreadParam *lpParam = new ThreadParam; //memset(lpParam, '/0', sizeof(ThreadParam)); lpParam->nTotal = nThreads; lpParam->nIndex = i; lpParam->nStart = nSegmentLength * i; lpParam->nEnd = lpParam->nStart + nSegmentLength - 1; if (lpParam->nEnd >= nFileSize) lpParam->nEnd = nFileSize - 1; AfxBeginThread(ServerWorkerThread, static_cast<LPVOID>(lpParam), THREAD_PRIORITY_NORMAL, 0, 0, NULL); //CreateThread(NULL, 0, ServerWorkerThread, (LPVOID)i, 0, 0); } return 0; } */ int CHttpDownload::FormatRequestHeader(void) { // char szHeader[1024]; return 0; } DWORD CHttpDownload::GetFileLength(const CString& strUrl) { CInternetSession sess; DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD; s_strUrl = strUrl; CHttpFile* pHttpFile = (CHttpFile* )sess.OpenURL(s_strUrl, 1, dwFlag); if (!pHttpFile) return -1; CString strLength; pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, strLength); pHttpFile->Close(); delete pHttpFile; return _ttoi(strLength); } // DownloadDlg.cpp : 实现文件 // #include "stdafx.h" #include "Download.h" #include "DownloadDlg.h" #include "./downloaddlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CDownloadDlg 对话框 CDownloadDlg::CDownloadDlg(CWnd* pParent /*=NULL*/) : CDialog(CDownloadDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pDownloader = NULL; } void CDownloadDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } //#define WM_XXXX 10O //const static int WM_DOWNLOADED_MESSAGE = WM_USER+100; BEGIN_MESSAGE_MAP(CDownloadDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_MESSAGE(WM_DOWNLOADED_MESSAGE, OnDownloadMessage) ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2) END_MESSAGE_MAP() // CDownloadDlg 消息处理程序 BOOL CDownloadDlg::OnInitDialog() { CDialog::OnInitDialog(); // 将/“关于.../”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 // GetDlgItem(IDC_EDIT1)->SetWindowText("http://codeproject.com/");//http://192.168.8.246:8080/sogou_wubi_15b.exe GetDlgItem(IDC_EDIT1)->SetWindowText("ftp://me:me@192.168.69.86/inet.h");//ftp://192.168.14.130/InstallPack/5.9.5.x/5.9.5.976/5.9.5.976.txt"); GetDlgItem(IDC_EDIT2)->SetWindowText("4"); return TRUE; // 除非设置了控件的焦点,否则返回 TRUE } void CDownloadDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CDownloadDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标显示。 HCURSOR CDownloadDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } #include "InternetDownload.h" #include "FtpDownload.h" #include "HttpDownload.h" void CDownloadDlg::OnBnClickedButton1() { CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST1); for (int i = pListBox->GetCount() - 1; i >= 0; i--) { pListBox->DeleteString( i ); } //downloader.Download("http://192.168.8.246:8080/sogou_wubi_15b.exe"); CString strUrl; GetDlgItem(IDC_EDIT1)->GetWindowText(strUrl); CString strThreads; CWnd* pEditCtrl = GetDlgItem(IDC_EDIT2); pEditCtrl->GetWindowText(strThreads); if (!strUrl.IsEmpty() && !strThreads.IsEmpty()) { GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); CString strServerName, strObject, strUserName, strPassword; DWORD dwServiceType; INTERNET_PORT nPort; if (!AfxParseURLEx(strUrl, dwServiceType, strServerName, strObject, nPort, strUserName, strPassword)) { TRACE(_T("Not a valid Quest! /n")); GetDlgItem(IDC_EDIT2)->EnableWindow(); GetDlgItem(IDC_EDIT2)->EnableWindow(); } if (dwServiceType == INTERNET_SERVICE_HTTP) { m_pDownloader = new CHttpDownload(this); m_pDownloader->Download(strUrl, _ttoi(strThreads)); } else if (dwServiceType = INTERNET_SERVICE_FTP) { m_pDownloader = new CFtpDownload(this); m_pDownloader->Download(strUrl, _ttoi(strThreads)); } else { TRACE(_T("Not a valid Quest! /n")); GetDlgItem(IDC_EDIT2)->EnableWindow(); GetDlgItem(IDC_EDIT2)->EnableWindow(); } //delete pDownloader; } else { AfxMessageBox("please input url & thread number"); return; } } LRESULT CDownloadDlg::OnDownloadMessage(WPARAM wParam, LPARAM lParam) { CString strInfo; strInfo.Format("part %d complete.", lParam); CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST1); pListBox->InsertString(pListBox->GetCount(), strInfo); CString strThreads; CWnd* pEditCtrl = GetDlgItem(IDC_EDIT2); pEditCtrl->GetWindowText(strThreads); if (pListBox->GetCount() == wParam) { //MergeFile(); CFile resultFile("c://temp.exe", CFile::modeCreate | CFile::modeWrite); if (!resultFile) return -1; char buffer[1024]; for (size_t i = 0; i < wParam; i++) { int nLength; CString strFileName; strFileName.Format("c:/temp.part%d", i); CFile tempFile(strFileName, CFile::modeRead); //nLength = file2.GetLength(); if (!tempFile) { AfxMessageBox("error: cannot find.."); return -1; } while ( (nLength = tempFile.Read(buffer, 1024)) > 0) { resultFile.Write(buffer, nLength); if (nLength < 1024) break; } tempFile.Close(); } resultFile.Close(); pListBox->InsertString(wParam, "Merge Ok!"); GetDlgItem(IDC_EDIT1)->EnableWindow(); GetDlgItem(IDC_EDIT2)->EnableWindow(); delete m_pDownloader; m_pDownloader = NULL; } return 0; } void CDownloadDlg::OnBnClickedButton2() { CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST1); for (int i = pListBox->GetCount() - 1; i >= 0; i--) { pListBox->DeleteString( i ); } }
前置知識 導入表 在一個可執行文件需要用到其餘DLL文件中的函數時,就需要用到導入表,用於記錄需要引用的函數。例如我們編寫的可執行文件需要用到CreateProcess函數,就需要用到kernel32.dll文件並且將其中的Create
7.0 LTS 盛大發布 Zabbix 7.0 LTS:極致性能和可擴展性 Zabbix LLC 發佈最新的長期支持(LTS)版本 - Zabbi
本文分享自華爲雲社區《使用MetaStudio生產線四步製作數字人視頻》,作者: yd_298097624。 隨着AIGC新技術尤其是大模型技術的發展,音視頻行業、數字內容生產行業正在經歷這從生產方式和生產效率上的一個巨大變化。預測到203
如今當用戶需要處理PDF文件時,通常不得不下載應用程序或者瀏覽器插件,控制用戶如何與PDF交互並不是一件容易的事。如果我們提供PDF作爲內容,用戶可以下載它並使用瀏覽器或PDF本身提供的控件進行交互。然而,一些企業可能希望控制用戶使用PDF
前言 小編之前分享過一篇文章叫《如何使用前端表格控件實現多數據源整合?》(可以放上文章的鏈接)。今天,繼續爲大家介紹如何使用前端表格控件來更新已連接的數據源信息。 環境準備 SpreadJS在線表格編輯器: SpreadJS 前端表格控件新
pt-osc原理探索及其觸發器的深入分析 > 作者:莫善,某互聯網公司高級 DBA。 > > 愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 > > 本文約 6000 字,預計閱讀需要 20 分鐘。 背景 自工
本文分享自華爲雲社區《一文徹底喫透MyBatis源碼!!》,作者:冰 河。 寫在前面 隨着互聯網的發展,越來越多的公司摒棄了Hibernate,而選擇擁抱了MyBatis。而且,很多大廠在面試的時候喜歡問MyBatis底層的原理和源碼實現
作者:天空小小 爲啥要寫? 從我接觸spring事務開始,就覺得這個東西很神奇,感覺實現很混亂,總是各種新的用法層出不窮。雖然懵懵懂懂的覺
這個其實是一個特別高頻的面試題,松哥也一直很想和大家仔細來聊一聊這個話題,網上關於這塊的文章很多,但是我一直覺得要把這個問題講清楚還有點難度,今天我來試一試,看能不能和小夥伴們把這個問題梳理清楚,當然,如果小夥伴們覺得看文章不過癮,松哥也有
分享8個開箱即用的API,方便日常處理集合。 1. 快速過濾空值:Stream.ofNullable 該方法是在 Java 9 中引入的,有助於過濾集合中的所有空值,從而可能使我們避免空指針異常。 在下面的示例中,有一個包含 null 的L
一、背景 在日常部門OpsReview過程中,部門內多次遇到應用容器所在的宿主機磁盤繁忙導致的接口響應緩慢,TP99增高等影響服務性能的問題,其中比較有效的解決方案是開啓日誌的異步打印,可以有效避免同步日誌打印在磁盤IO高起的情況下拖慢業
本文分享自華爲雲社區《【MySQL技術專欄】MySQL8.0直方圖介紹》,作者:GaussDB 數據庫。 背景 數據庫查詢優化器負責將SQL查詢轉換爲儘可能高效的執行計劃,但因爲數據環境不斷變化導致優化器對查詢數據瞭解的不夠充足,可能無法
每篇一句 大魔王張怡寧:女兒,這堆金牌你拿去玩吧,但我的銀牌不能給你玩。你要想玩銀牌就去找你王浩叔叔吧,他那銀牌多 前言 爲了講述好Spring MVC最爲複雜的數據綁定這塊,我前面可謂是做足了功課,對此部分知識此處給小夥伴留一個學
引入依賴 <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId>
腳本 項目根目錄下創建shell文件夾,創建 cabinet.sh 腳本: #!/bin/bash # 應用名 APP_NAME=cabinet-service-test PROG_NAME=$0 ACTION=$1 APP_START