博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何使用 WinInet 时提供下载上载进度信息
阅读量:4446 次
发布时间:2019-06-07

本文共 4558 字,大约阅读时间需要 15 分钟。

概要

许多开发人员都使用 WinInet 函数来下载或上载文件在 Internet 上的想要提供一个进度条以指示多少文件传输已完成,但多少就越长。您可以使用以下机制来完成此。
Collapse image更多信息
使用 InternetSetStatusCallback 来获取下载进度的通知为您提供良好的信息请求的进展如何,包括连接状态通知。但是,它不表示一定百分比的传输已完成。
若要获取的百分比相当完整的通知,您需要确定传输的大小,然后使用小缓冲区中调用 InternetReadFile 或 InternetWriteFile。然后,您可以作为完整的函数调用来计算传输的百分比。
例如,假设您想要下载的 1000 个字节的文件。而不是进行一次调用 InternetReadFile 1000 字节的缓冲区,可以拨打 10 InternetReadFIle 与 100 字节的缓冲区。通过这种方式完成每次调用 InternetReadFile,您知道下载是另一个完整的 10%。
下面的代码说明了此过程:

#include
#include
#include
void main(int argc, char *argv[]){ if (argc != 3) { cout << "Usage: progress
" << endl; return; } HINTERNET hSession = InternetOpen("WinInet Progress Sample", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); HINTERNET hConnection = InternetConnect(hSession, argv[1], // Server INTERNET_DEFAULT_HTTP_PORT, NULL, // Username NULL, // Password INTERNET_SERVICE_HTTP, 0, // Synchronous NULL); // No Context HINTERNET hRequest = HttpOpenRequest(hConnection, "GET", argv[2], NULL, // Default HTTP Version NULL, // No Referer (const char**)"*/*\0", // Accept // anything 0, // Flags NULL); // No Context HttpSendRequest(hRequest, NULL, // No extra headers 0, // Header length NULL, // No Body 0); // Body length DWORD dwContentLen; DWORD dwBufLen = sizeof(dwContentLen); if (HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwContentLen, &dwBufLen, 0)) { // You have a content length so you can calculate percent complete char *pData = (char*)GlobalAlloc(GMEM_FIXED, dwContentLen + 1); DWORD dwReadSize = dwContentLen / 10; // We will read 10% of data // with each read. cout << "Download Progress:" << endl; cout << " 0----------100%" << endl; cout << " "; cout.flush(); DWORD cReadCount; DWORD dwBytesRead; char *pCopyPtr = pData; for (cReadCount = 0; cReadCount < 10; cReadCount++) { InternetReadFile(hRequest, pCopyPtr, dwReadSize, &dwBytesRead); cout << "*"; cout.flush(); pCopyPtr = pCopyPtr + dwBytesRead; } // extra read to account for integer division round off InternetReadFile(hRequest, pCopyPtr, dwContentLen - (pCopyPtr - pData), &dwBytesRead); // Null terminate data pData[dwContentLen] = 0; // Display cout << endl << "Download Complete" << endl; cout << pData; } else { DWORD err = GetLastError(); // No content length...impossible to calculate % complete // Just read until we are done. char pData[100]; DWORD dwBytesRead = 1; while (dwBytesRead) { InternetReadFile(hRequest, pData, 99, &dwBytesRead); pData[dwBytesRead] = 0; cout << pData; } }}

 

                
有几点需要注意的使用这种方法时:
    在开始之前,您必须知道的数据大小。上面的代码将尝试通过阅读使用 HttpQueryInfo 函数的 HTTP 内容长度标头来确定数据大小。尽管许多 HTTP 响应中包括的内容长度标头,则不需要。除非您有另一种机制,用于获取数据的大小,您将不能计算进度,如果在响应中未包括的内容长度标头。
    如果您试图上载或下载 FTP 资源中,您将不能使用 FtpPutFile 或 FtpGetFile,并希望确定进度信息。您应该使用 FtpOpenFile,然后使用 InternetReadFile 和 InternetWriteFile,如上面所述。
    因为提供进度的信息假定您必须知道数据的大小,可以使用 FtpGetFileSize 来下载文件之前获取 FTP 资源的大小。请注意 FtpGetFileSize 并不总是成功由于多种 FTP 服务器返回目录列表信息的方式获取的文件大小。有关使用 FTP 来获取目录列表信息的问题的其他信息,请参阅下面 Microsoft 知识库中相应的文章:
    172712信息: 限制的 WinInet FTP 功能

转载于:https://www.cnblogs.com/microzone/p/3383236.html

你可能感兴趣的文章
Edit显示行号
查看>>
取得字符串中指定的字符str[]
查看>>
delphi TOpenDialog
查看>>
vue - 子路由-路由嵌套
查看>>
static关键字用法
查看>>
JVM调优总结
查看>>
从yum提示空间不足到根分区扩容
查看>>
关于编程的思考
查看>>
20款最佳jQuery应用程序和框架(上)
查看>>
git安装和使用
查看>>
数据类型转换
查看>>
CycleGAN 各种变变变
查看>>
Nodejs学习笔记(2) 阻塞/非阻塞实例 与 Nodejs事件
查看>>
跟我一起读postgresql源码(六)——Executor(查询执行模块之——查询执行策略)
查看>>
scala的4中for循环,及while和do while循环
查看>>
Lesson_10 作业----计算工资
查看>>
vue.js windows下开发环境搭建
查看>>
数据表改变之后数据的迁移
查看>>
e生保plus
查看>>
雷林鹏分享:Ruby 环境变量
查看>>