请教高手关于文件下载的问题!(附代码)

ilgold 2002-12-02 10:55:29
小弟VC初学,碰到一个文件下载的问题,望大虾不吝赐教!

int nRetCode = 0;

CInternetSession objSession;
CHttpConnection* pServer = NULL;
CHttpFile* pFile = NULL;

try
{
UpdateData();
pszURL = m_URL;

CString strServerName;
CString strObject;
CString strFilePath;
INTERNET_PORT nPort;
DWORD dwServiceType;
UINT nBytesRead = 1;
DWORD nFileSize = 0;


//Parse the URL ...
if (AfxParseURL(pszURL, dwServiceType, strServerName, strObject, nPort) &&
dwServiceType == INTERNET_SERVICE_HTTP)
{
//Connect a web server ...
pServer = objSession.GetHttpConnection(strServerName, nPort);
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
pFile->AddRequestHeaders(szHeaders);
pFile->SendRequest();

DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);

if (dwRet == HTTP_STATUS_OK) {

//Find a valid file ...
CFileDialog objDLG(false, "*", pFile->GetFileName());;
objDLG.DoModal();
strFilePath = objDLG.GetPathName();
//问题1
//无论用CInternetFile的GetLength()方法,还是用InternetQueryDataAvailable
//都无法得到大文件的大小,小文件则可以

nFileSize = pFile->GetLength();
InternetQueryDataAvailable(pFile, &nFileSize, 0, 0);

CString szBuffer;
CFile tmpFile(strFilePath, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
CArchive ar(&tmpFile, CArchive::store);
long nSize = 0;
//Read file from web server ...

//问题2,ReadString以文件流的形式一行一行的从web server上读取
//小文件无问题,大文件有时候读不全
while (pFile->ReadString(szBuffer)) {
ar << szBuffer;
nSize += szBuffer.GetLength();
}

ar.Close();
tmpFile.Close();
pFile->Close();

}


}
}
catch (CInternetException* pEx)
{
TCHAR szErr[1024];
pEx->GetErrorMessage(szErr, 1024);

nRetCode = 2;
pEx->Delete();
}


综上所述,下载大文件总会碰到很多问题!谁有经验,请帮帮忙
Socket编程比较麻烦,碰到的问题可能会更多,而且关于http代理不好解决
wininet还是比较方便的,但是没我想象的那么有效
...全文
71 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
robothn 2002-12-05
  • 打赏
  • 举报
回复
DownProgress: 5042 2968978 4 http://newhua.ruyi.com/down/lkmn65.exe
log已经很清楚了:
if(ulStatusCode == 4)
m_pNotifyWnd->SendMessage(WM_HTTPDOWN_NOTIFY, HTTPDOWN_MAXSIZE, ulProgressMax);// get file size
没试过50M以上的大文件
ilgold 2002-12-04
  • 打赏
  • 举报
回复
将贴子提前不管用?顶一下!
ilgold 2002-12-03
  • 打赏
  • 举报
回复
杆协回复,但是
CAsyncMonikerFile同样存在上述两个问题!

robothn 2002-12-02
  • 打赏
  • 举报
回复
我以前用的代码,现在不需要这么多信息,用WINAPI ::URLDownloadToFile(...)
代理嘛,我没试过,你试试吧
robothn 2002-12-02
  • 打赏
  • 举报
回复
// HttpDown.cpp: implementation of the CHttpDown class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HttpDown.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHttpDown::CHttpDown()
:m_iMode(0), m_hBuf(NULL), m_pNotifyWnd(NULL), m_sLocalFile(_T("")), m_sTempFile(_T(""))
{
}

CHttpDown::~CHttpDown()
{
}

void CHttpDown::OpenUrl(LPCTSTR lpszUrl, HGLOBAL hBuf, CWnd* pNotifyWnd)
{
ASSERT(hBuf !=NULL && pNotifyWnd != NULL);
m_hBuf = hBuf;
m_pNotifyWnd = pNotifyWnd;
m_iMode = 1; // Down to buffer: m_hBuf
TRACE(_T("From AsyncMonikerFile -> Openning url: %s.\n"), lpszUrl);
Open(lpszUrl);
}

void CHttpDown::OpenUrl(LPCTSTR lpszUrl, LPCTSTR lpszLocalFile, CWnd* pNotifyWnd)
{
ASSERT(lpszLocalFile != NULL && pNotifyWnd !=NULL);
m_sLocalFile = lpszLocalFile;
m_pNotifyWnd = pNotifyWnd;
m_iMode = 2; // Down to file: m_sLocalFile
TRACE(_T("From AsyncMonikerFile -> Opening url: %s.\n"), lpszUrl);
Open(lpszUrl);
}

void CHttpDown::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
{
TRACE(_T("."));
if( (bscfFlag & BSCF_LASTDATANOTIFICATION) != 0 )
{
ASSERT(::IsWindow(m_pNotifyWnd->m_hWnd));
TRACE(_T(".\n"));
DWORD read_total = 0;
try
{
if(m_iMode == 1)
{
LPSTR lpMem;
if((lpMem = (LPSTR)::GlobalLock(m_hBuf)) == NULL)
{
TRACE(_T("From AsyncMonikerFile -> Memory low.\n"));
m_pNotifyWnd->SendMessage(WM_HTTPDOWN_NOTIFY, HTTPDOWN_ERROR, HTTPDOWN_ERROR_MEMORYLOW); // Memory low
return;
}
if((read_total = Read(lpMem, dwSize)) != dwSize)
{
TRACE(_T("From AsyncMonikerFile -> Note: size mismatch.\n"));
}
::GlobalUnlock(m_hBuf);
}
else if(m_iMode == 2)
{
const int READ_BLOCK_SIZE = 1024*32;
PBYTE buf = new BYTE[READ_BLOCK_SIZE];
DWORD read_once;
CFile ofile(m_sLocalFile, CFile::modeCreate|CFile::modeWrite);
while( (read_once = Read(buf, READ_BLOCK_SIZE)) > 0 )
{
ofile.Write(buf, read_once);
read_total += read_once;
}
ofile.Close();
delete []buf;
}
else
ASSERT(FALSE); // Mode invalid
/*
// Delete temp file generated by CAsyncMonikerFile
if( !m_sTempFile.IsEmpty() && ::CopyFile(m_sTempFile, _T("e:\\books\\acdsee42.exe"), TRUE) )
{
TRACE(_T("From AsyncMonikerFile -> delete temp file: %s.\n"), m_sTempFile);
}
*/
TRACE(_T("From AsyncMonikerFile -> read size: %d Save as file: %s.\n"), read_total, m_sLocalFile);
m_pNotifyWnd->SendMessage(WM_HTTPDOWN_NOTIFY, HTTPDOWN_END, (LPARAM)(LPCTSTR(m_sLocalFile)) ); // down success

}
catch(CFileException* e)
{
e->Delete();
m_pNotifyWnd->SendMessage(WM_HTTPDOWN_NOTIFY, HTTPDOWN_ERROR, HTTPDOWN_ERROR_FILEEXCEPTION); // exception occupied
}
}

CAsyncMonikerFile::OnDataAvailable(dwSize, bscfFlag);
}

void CHttpDown::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCTSTR szStatusText)
{
// TRACE(_T("DownProgress: %d %d %x %s\n"), ulProgress, ulProgressMax, ulStatusCode, szStatusText);
/* log:
DownProgress: 0 0 1 newhua.ruyi.com
DownProgress: 0 0 2 211.97.168.175
DownProgress: 0 0 b (null)
DownProgress: 0 0 d application/x-msdownload
DownProgress: 5042 2968978 4 http://newhua.ruyi.com/down/lkmn65.exe
DownProgress: 5042 2968978 e C:\Documents and Settings\nsw\Local Settings\Temporary Internet Files\Content.IE5\SGOENAX9\lkmn65[1].exe
.DownProgress: 31262 2968978 5 http://newhua.ruyi.com/down/lkmn65.exe
.DownProgress: 32642 2968978 5 http://newhua.ruyi.com/down/lkmn65.exe
*/
if(ulStatusCode == 4)
m_pNotifyWnd->SendMessage(WM_HTTPDOWN_NOTIFY, HTTPDOWN_MAXSIZE, ulProgressMax);// get file size
else if(ulStatusCode == 5)
m_pNotifyWnd->SendMessage(WM_HTTPDOWN_NOTIFY, HTTPDOWN_CURRENTSIZE, ulProgress);// get file size
else if(ulStatusCode == 0xe)
{
m_sTempFile = szStatusText; // save temp filename, prepare delete it
}

CAsyncMonikerFile::OnProgress(ulProgress, ulProgressMax, ulStatusCode, szStatusText);
}
robothn 2002-12-02
  • 打赏
  • 举报
回复
#if !defined(AFX_HTTPDOWN_H__8109AA66_4C2F_4EB4_99D3_78F04DFC0E5B__INCLUDED_)
#define AFX_HTTPDOWN_H__8109AA66_4C2F_4EB4_99D3_78F04DFC0E5B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <afxole.h>

#define WM_HTTPDOWN_NOTIFY WM_USER+1

#define HTTPDOWN_START 1
#define HTTPDOWN_END 2
#define HTTPDOWN_ERROR 3
#define HTTPDOWN_MAXSIZE 4
#define HTTPDOWN_CURRENTSIZE 5

#define HTTPDOWN_ERROR_MEMORYLOW 1
#define HTTPDOWN_ERROR_FILEEXCEPTION 2

class CHttpDown : public CAsyncMonikerFile
{
public:
CHttpDown();
virtual ~CHttpDown();

void OpenUrl(LPCTSTR lpszUrl, HGLOBAL hBuf, CWnd* pNotifyWnd);
void OpenUrl(LPCTSTR lpszUrl, LPCTSTR lpszLocalFile, CWnd* pNotifyWnd);

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHttpDown)
protected:
virtual void OnDataAvailable(DWORD dwSize, DWORD bscfFlag);
virtual void OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCTSTR szStatusText);
//}}AFX_VIRTUAL

// Generated message map functions
//{{AFX_MSG(CHttpDown)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

// Implementation
protected:
HGLOBAL m_hBuf;
CString m_sLocalFile; // Download save as file
CString m_sTempFile; // Download generated temp file
int m_iMode; // 1: Down to buffer, 2: Down to file
CWnd* m_pNotifyWnd; // SendMessage() target window
};

#endif // !defined(AFX_HTTPDOWN_H__8109AA66_4C2F_4EB4_99D3_78F04DFC0E5B__INCLUDED_)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧