解决InternetReadFile下载带有中文字符的文件失败的方案

来源:互联网 发布:淘宝 户外头巾 编辑:程序博客网 时间:2024/04/28 15:03

如下代码:

// HttpDownFileDemo.cpp : 定义控制台应用程序的入口点。//这是一个Http下载文件的例子#include "stdafx.h"#include <iostream>using namespace std;#include <windows.h>#include <Nb30.h>#include <wininet.h>#pragma comment(lib, "Wininet.lib") #pragma comment(lib, "NetApi32.lib") //初始化HANDLE InitHttpRequest(LPCTSTR pszFile);//写入文件void WriteFileBuffer(HANDLE File,char *pBuff, DWORD dwLen);//入口函数int _tmain(int argc, _TCHAR* argv[]){//文件句柄HANDLE m_hFile;//本地文件路径TCHAR szLocalFile[MAX_PATH];//初始化ZeroMemory(szLocalFile,sizeof(szLocalFile));//本地路径lstrcpyn(szLocalFile,TEXT("C:\\按钮.png"),sizeof(szLocalFile));//初始化本地文件m_hFile = InitHttpRequest(szLocalFile);//初始化HINTERNET hSession = InternetOpen(TEXT("UrlTest"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);//下载路径std::string strRequestFileGBK = "http://183.131.195.49:81//GameClient//res/GamePlaza/Face/按钮.png";//打开文件HINTERNET hHttp = InternetOpenUrlA(hSession, strRequestFileGBK.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);if(hHttp){char Temp[1024];      ULONG Number = 1;while (Number > 0){BOOL bReadFile = InternetReadFile(hHttp, Temp, 1024 - 1, &Number);if(bReadFile == FALSE){cout << "文件下载异常,错误Code:" << GetLastError() << endl;break;}//写入数据WriteFileBuffer(m_hFile,Temp, Number); }InternetCloseHandle(hHttp);InternetCloseHandle(hSession);}else{cout << "文件打开异常,错误Code:" << GetLastError() << endl;InternetCloseHandle(hSession);}//关闭文件if (m_hFile){CloseHandle(m_hFile);m_hFile = NULL;}system("pause");return 0;}//写入数据void WriteFileBuffer(HANDLE File,char *pBuff, DWORD dwLen){if (dwLen<=0)return;WriteFile(File, pBuff, dwLen, &dwLen, NULL);}//初始化请求HANDLE InitHttpRequest(LPCTSTR pszFile){HANDLE File = CreateFile(pszFile, GENERIC_READ|GENERIC_WRITE,//允许读写该文件0,NULL,OPEN_ALWAYS,//如果存在就打开文件,否则创建FILE_ATTRIBUTE_NORMAL,NULL);if (File==INVALID_HANDLE_VALUE)return File;DWORD dwFileCurrySize = GetFileSize(File, NULL) ; if (dwFileCurrySize == -1)return File;SetFilePointer(File, 0,0,FILE_END);return File;}
上面这个Demo程序下载一般的文件是没有问题的,唯独下载带有中文字符的文件会出现下载失败的问题,如下图:


最终读取到的内容会提示“找不到文件或目录”,也就会导致下载失败,解决这个问题也很简单,如下代码:

增加一个GBK转UTF8的方法:

//GBK转UTF8string GBKToUTF8(const std::string& strGBK){string strOutUTF8 = "";WCHAR * str1;int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);str1 = new WCHAR[n];MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);char * str2 = new char[n];WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);strOutUTF8 = str2;delete[]str1;str1 = NULL;delete[]str2;str2 = NULL;return strOutUTF8;}
再将红色背景代码块替换为:

//下载路径std::string strRequestFileGBK = "http://183.131.195.49:81//GameClient//res/GamePlaza/Face/按钮.png";//GBK转UTF8std::string strRequestFileUTF8 = GBKToUTF8(strRequestFileGBK);//打开文件HINTERNET hHttp = InternetOpenUrlA(hSession, strRequestFileUTF8.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);

再次下载问题得到解决,只要将要打开的地址从GBK转换为UTF8,再使用InternetOpenUrlA打开,就没有问题了。

点击下载工程代码(VS2010)


0 0