curl获取下载状态、下载进度

一、获取下载结果(成功或失败)方法

使用curl命令下载文件,通过--progress-bar获取进度,通过读取打印结果判断下载完成情况。
正常下载完成,curl打印信息如下:

#=#=#                                                                         
##O#-#                                                                        
##O=#  #                                                                      
#=#=-#  #                                                                     

                                                                           0.0%
                                                                           0.1%
                                                                           0.1%
                                                                           0.1%
                                                                           0.2%
                                                                           0.2%
                                                                           0.3%
                                                                           0.3%
                                                                           0.4%
                                                                           0.4%
                                                                           0.4%
                                                                           0.5%
                                                                           0.6%
                                                                           0.6%
                                                                           0.7%
                                                                           0.8%
                                                                           0.9%
                                                                           0.9%
                                                                           0.9%
                                                                           1.0%
#####################################################################     96.1%
#####################################################################     96.8%
#####################################################################     97.0%
#####################################################################     97.2%
######################################################################    97.3%
######################################################################    97.7%
######################################################################    97.9%
######################################################################    98.1%
######################################################################    98.2%
######################################################################    98.4%
######################################################################    98.6%
#######################################################################   98.8%
#######################################################################   98.9%
#######################################################################   99.1%
#######################################################################   99.3%
#######################################################################   99.6%
#######################################################################   99.7%
#######################################################################  100.0%
######################################################################## 100.0%

下载过程中异常,curl打印信息如下:

#=#=#                                                                         
##O#-#                                                                        
##O=#  #                                                                      
#=#=-#  #                                                                     
-#O#- #   #                                                                   
-=#=#   #   #                                                                 
-=O#-#   #   #                                                                
-=O=#  #   #   #                                                              

                                                                           0.0%
                                                                           0.1%
                                                                           0.1%
                                                                           0.1%
                                                                           0.1%
                                                                           0.2%
                                                                           0.2%
                                                                           0.3%
                                                                           0.3%
                                                                           0.3%
                                                                           0.3%
                                                                           0.3%
                                                                           0.3%curl: (18) Recv failure: Connection was reset

下载文件(成功或失败)代码

#include "stdafx.h"
#include <ShlObj.h>
#include <string>

int main()
{
	bool bDownloadSuccess = false;
	SHELLEXECUTEINFO sei;
	ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.nShow = SW_HIDE;
	sei.fMask = SEE_MASK_NOCLOSEPROCESS;
	sei.hInstApp = NULL;
	sei.lpVerb = NULL;
	sei.lpVerb = _T("open");
	sei.lpFile = _T("cmd");
	sei.lpParameters = _T("/c curl.exe -o d:\\downloadfile.zip http://repository.maemo.org/pool/maemo3.2/free/binary/apt_0.6.42.3osso19_armel.deb --progress-bar > d:\\3.log 2>&1");//程序的参数
	sei.lpDirectory = _T("C:\\Users\\Administrator\\Downloads\\curl-8.0.1_7-win32\\curl-8.0.1_7-win64-mingw\\bin");
	if (ShellExecuteEx(&sei))//执行成功
	{
		if (sei.hProcess)//指定 SEE_MASK_NOCLOSEPROCESS 并其成功执行,则 hProcess 将会返回执行成功的进程句柄
		{
			WaitForSingleObject(sei.hProcess, INFINITE);//等待执行完毕
			if (sei.hProcess != NULL)
			{
				CloseHandle(sei.hProcess);
				sei.hProcess = NULL;
			}
			//读取log文件
			FILE * fLogFile = NULL;
			errno_t errnoFile = fopen_s(&fLogFile, "d:\\3.log", "r");
			if (0 == errnoFile && fLogFile != NULL)
			{
				fseek(fLogFile, 0, SEEK_END);
				unsigned long  uTotalSize = ftell(fLogFile);
				fseek(fLogFile, -8, SEEK_END);
				char szProgerss[1024] = { 0 };
				fread(szProgerss, 1, 8, fLogFile);
				if (strstr(szProgerss, "100.0%") != NULL)
				{
					bDownloadSuccess = true;
					printf("download success.\n");
				}
				else
				{
					memset(szProgerss, 0, sizeof(szProgerss));
					if (uTotalSize >= 512)
					{
						fseek(fLogFile, -512, SEEK_END);
						fread(szProgerss, 1, 512, fLogFile);
					}
					else
					{
						fseek(fLogFile, 0, SEEK_SET);
						fread(szProgerss, 1, uTotalSize, fLogFile);
					}
					std::string strFailBecause = "";
					std::string strResult = szProgerss;
					std::size_t posBegin = strResult.rfind("curl:");
					if (posBegin != std::string::npos)
					{
						std::size_t posEnd = strResult.find("\n", posBegin + strlen("curl:"));
						if (posEnd != std::string::npos)
						{
							strFailBecause = strResult.substr(posBegin, posEnd - posBegin);
						}
						else
						{
							strFailBecause = strResult.substr(posBegin);
						}
					}
					printf("download fail. %s\n", strFailBecause.c_str());
				}

				fclose(fLogFile);
			}

			DeleteFile(_T("d:\\3.log"));
		}
	}
	
	system("pause");
    return 0;
}

二、获取下载进度方法

使用curl命令下载文件,通过--progress-bar获取进度,通过定时读取(共享文件读)打印结果判断下载进度情况。

获取下载进度代码

#include "stdafx.h"
#include <ShlObj.h>
#include <string>

void FileProgress(const char *pFilePath, bool bWaitFileProcessExit, bool & bIsSuccess, float & fProgess, std::string & strBecause)
{
	bIsSuccess = false;
	strBecause = "";

	FILE * fLogFile = NULL;
	fLogFile = _fsopen(pFilePath, "r", _SH_DENYNO);//共享读
	if (fLogFile != NULL)
	{
		fseek(fLogFile, 0, SEEK_END);
		unsigned long  uTotalSize = ftell(fLogFile);
		fseek(fLogFile, -8, SEEK_END);
		char szProgerss[1024] = { 0 };
		fread(szProgerss, 1, 8, fLogFile);
		if (strstr(szProgerss, "100.0%") != NULL)
		{
			fProgess = 100.0;
			bIsSuccess = true;
			printf("download success. progress:100.0\n");
		}
		else
		{
			if (bWaitFileProcessExit)
			{
				memset(szProgerss, 0, sizeof(szProgerss));
				if (uTotalSize >= 256)
				{
					fseek(fLogFile, -256, SEEK_END);
					fread(szProgerss, 1, 256, fLogFile);
				}
				else
				{
					fseek(fLogFile, 0, SEEK_SET);
					fread(szProgerss, 1, uTotalSize, fLogFile);
				}
				std::string strFailBecause = "";
				std::string strResult = szProgerss;
				std::size_t posBegin = strResult.rfind("curl:");
				if (posBegin != std::string::npos)
				{
					std::size_t posEnd = strResult.find("\n", posBegin + strlen("curl:"));
					if (posEnd != std::string::npos)
					{
						strFailBecause = strResult.substr(posBegin, posEnd - posBegin);
					}
					else
					{
						strFailBecause = strResult.substr(posBegin);
					}
				}
				strBecause = strFailBecause;
				printf("download fail. %s\n", strFailBecause.c_str());
			}
			else
			{
				memset(szProgerss, 0, sizeof(szProgerss));
				if (uTotalSize >= 256)
				{
					fseek(fLogFile, -256, SEEK_END);
					fread(szProgerss, 1, 256, fLogFile);
				}
				else
				{
					fseek(fLogFile, 0, SEEK_SET);
					fread(szProgerss, 1, uTotalSize, fLogFile);
				}
				std::string strProgress = "";
				std::string strResult = szProgerss;
				std::size_t posEnd = strResult.rfind("%");
				if (posEnd != std::string::npos)
				{
					std::size_t posBegin = strResult.rfind(" ", posEnd + 1);
					if (posBegin != std::string::npos)
					{
						strProgress = strResult.substr(posBegin+1, posEnd - posBegin - 1);
					}
				}
				fProgess = atof(strProgress.c_str());
				printf("download progress:%.1f\n", fProgess);
			}
		}

		fclose(fLogFile);
		fLogFile = NULL;
	}
	else
	{
		fProgess = 0;
	}
}


int main()
{
	bool bDownloadSuccess = false;
	SHELLEXECUTEINFO sei;
	ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.nShow = SW_HIDE;
	sei.fMask = SEE_MASK_NOCLOSEPROCESS;
	sei.hInstApp = NULL;
	sei.lpVerb = NULL;
	sei.lpVerb = _T("open");
	sei.lpFile = _T("cmd");
	sei.lpParameters = _T("/c curl.exe -o d:\\downloadfile.zip http://repository.maemo.org/pool/maemo3.2/free/binary/apt_0.6.42.3osso19_armel.deb --progress-bar > d:\\4.log 2>&1");//程序的参数
	sei.lpDirectory = _T("C:\\Users\\Administrator\\Downloads\\curl-8.0.1_7-win32\\curl-8.0.1_7-win64-mingw\\bin");
	if (ShellExecuteEx(&sei))//执行成功
	{
		if (sei.hProcess)//指定 SEE_MASK_NOCLOSEPROCESS 并其成功执行,则 hProcess 将会返回执行成功的进程句柄
		{
			bool bIsDownloadSuccess = false;
			float fDownloadProgress = 0;
			std::string strDownloadFailBecause = "";
			DWORD dwRet = 0;
			while (true)
			{
				dwRet = WaitForSingleObject(sei.hProcess, 500);
				if (dwRet == WAIT_OBJECT_0)
				{
					//读取log文件
					FileProgress("d:\\4.log", true, bIsDownloadSuccess, fDownloadProgress, strDownloadFailBecause);
					break;
				}
				else if (dwRet == WAIT_TIMEOUT)
				{
					//读取log文件
					FileProgress("d:\\4.log", false, bIsDownloadSuccess, fDownloadProgress, strDownloadFailBecause);
					continue;
				}
				else
				{
					//读取log文件
					FileProgress("d:\\4.log", false, bIsDownloadSuccess, fDownloadProgress, strDownloadFailBecause);
					continue;
				}
			}
			if (sei.hProcess != NULL)
			{
				CloseHandle(sei.hProcess);
				sei.hProcess = NULL;
			}

			printf("download status:%d progress:%.1f failBeacuse:%s\n", bIsDownloadSuccess == true ? 1 : 0, fDownloadProgress, strDownloadFailBecause.c_str());

			DeleteFile(_T("d:\\4.log"));	
		}
	}
	
	system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/byxdaz/article/details/130306132
今日推荐