龙空技术网

windows下C语言使用curl库访问HTTP下载文件

DS小龙哥 71

前言:

此时看官们对“c语言如何保存文件到文件夹”大致比较注意,朋友们都需要分析一些“c语言如何保存文件到文件夹”的相关内容。那么小编同时在网络上汇集了一些有关“c语言如何保存文件到文件夹””的相关文章,希望同学们能喜欢,小伙伴们快快来了解一下吧!

一、前言

cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。

cURL支持的通信协议有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。

curl还支持SSL认证、HTTP POST、HTTP PUT、FTP上传, HTTP form based upload、proxies、HTTP/2、cookies、用户名+密码认证(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos)、file transfer resume、proxy tunneling。

二、curl下载

curl for windows :

下载页面如图:

解压后的可执行文件位置:

下面是解压后的文件目录:

在命令行使用curl测试下载文件:

三、通过命令行使用curl

curl可以直接调用函数库完成功能设计、也可以直接调用可执行文件完成需要的功能,下面这里就介绍,在windows下,通过CreateProcess调用curl命令函数完成文件下载。使用curl实现HTTP协议文件下载成功,通过给定的连接地址,可以完成文件下载,百分比进度返回等等。

 /************************************************** 作者: DS小龙哥 功能: 执行命令 参数解释: CallBackFunction_p func_p  :回调函数,用于通知进度执行过程 char *text  //进度的转码过程,详细描述.描述当前这个操作是做什么. char *total_time   //执行的总时间 char *cmd //执行的命令 **************************************************/ int file_down_func(CallBackFunction_p func_p, const char *text, const char *total_time, const  char *cmd) {         BOOL run_pipe;          PROCESS_INFORMATION pi;         STARTUPINFO si;         BOOL ret = FALSE;         DWORD flags = CREATE_NO_WINDOW;           char pBuffer[210];         SECURITY_ATTRIBUTES sa;         sa.nLength = sizeof(SECURITY_ATTRIBUTES);         sa.lpSecurityDescriptor = NULL;         sa.bInheritHandle = TRUE;         HANDLE hReadPipe, hWritePipe;         run_pipe = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);          if (run_pipe != 1)         {             printf("创建匿名管道文件失败=%d\n", run_pipe);             return -1;         }          ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));         ZeroMemory(&si, sizeof(STARTUPINFO));         si.cb = sizeof(STARTUPINFO);         si.dwFlags |= STARTF_USESTDHANDLES;         si.hStdInput = NULL;         si.hStdError = hWritePipe;         si.hStdOutput = hWritePipe;          wchar_t cmd_wchar[1024];         CharToWchar(cmd, cmd_wchar);          //TCHAR cmd[] = TEXT("ffmpeg -i D:\123.mp4 -vf reverse D:\out\out1.mp4");          ret = CreateProcess(NULL, cmd_wchar, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);          if (ret)         {             while (true)             {                 DWORD ExitCode = 0;                 //判断进程是否执行结束                 printf("正在执行...GetExitCodeProcess\r\n");                 GetExitCodeProcess(pi.hProcess, &ExitCode);                 printf("ExitCode:%d\r\n", ExitCode);                 if (ExitCode == STILL_ACTIVE) //正在运行                 {                     DWORD RSize = 0;                     BOOL run_s = 0;                     printf("正在执行...ReadFile\r\n");                     run_s = ReadFile(hReadPipe, pBuffer, sizeof(pBuffer), &RSize, NULL);                     pBuffer[RSize - 1] = '\0';                      printf("执行过程:%s,%d,%d,%s\n", version_str, run_s, RSize, pBuffer);                      char number_buff[10]="\0"; //存放百分比                      printf("pBuffer=%s\r\n", pBuffer);                     //通过回调函数向外部返回进度提示                     for (size_t i = 0; i < 10 && pBuffer[i]!='\0'; i++)                     {                         if (pBuffer[i] >= '0' && pBuffer[i] <= '9')                         {                             //得到百分比值                             for (size_t j = 0; j < 9 && pBuffer[i+j] != '\0'; j++)                             {                                 //printf("@@%c@@\r\n", pBuffer[i + j]);                                 if (pBuffer[i+j] >= '0' && pBuffer[i+j] <= '9')                                 {                                     number_buff[j] = pBuffer[i + j];                                 }                                 else                                 {                                     number_buff[j] = '\0';                                     break;                                 }                             }                             break;                         }                     }                      //  0  926M    0 6463k    0     0  7378k      0  0:02:08 --:--:--  0:02:08 7386                     //如果找到进度的位置                     if (strlen(number_buff)>0)                     {                         std::string  out_str;                          out_str = text;                         out_str += ",";                         out_str += "100";                         out_str += ",";                         out_str += number_buff;                          printf("回调:%s\r\n", out_str.c_str());                         //将执行的结果再回调出去                         if (func_p)                         {                             func_p(out_str.c_str());                         }                     }                 }                 else //结束                 {                     printf("执行完毕,ExitCode=%d\r\n", ExitCode);                     break;                 }             }              printf("正在等待子进程结束....\n");             //等待结束             WaitForSingleObject(pi.hProcess, INFINITE);              CloseHandle(pi.hProcess);             CloseHandle(pi.hThread);             printf("子进程执行完毕....\n");             return 0;         }         printf("子进程创建失败:%d\n", ret);     return -1; }    int main() {         string VideoCacheFilePath = "D:\out";      //下载的文件名称     string file_path = "哈哈哈.MP4";      //如果返回为真就表示是网络地址     if (strstr(file_path.c_str(), "http:") ||         strstr(file_path.c_str(), "https:"))     {         //1.获取不带路径的文件名         string::size_type iPos;         if (strstr(file_path.c_str(), "\"))         {             iPos = file_path.find_last_of('\') + 1;         }         else         {             iPos = file_path.find_last_of('/') + 1;         }          //得到文件名称         string base_file = file_path.substr(iPos, file_path.length() - iPos);          //得到完整的文件下载存储路径         string VideoPath_tmp = VideoCacheFilePath;         VideoPath_tmp += "\";         VideoPath_tmp += base_file;          //判断文件是否存在         printf("文件存储路径:%s\r\n", VideoPath_tmp.c_str());         FILE *file_p = fopen(VideoPath_tmp.c_str(),"rb");         //不存在就下载         if (file_p == nullptr)         {             //切换目录,进入到curl命令所在的目录             _chdir(VideoCacheFilePath.c_str());              string cmd = "curl -O ";             cmd += file_path;             //启动下载文件             file_down_func(NULL, base_file.c_str(),"100",cmd.c_str());         }         else         {             printf("文件存在不需要下载.\r\n");             fclose(file_p);         }     }     return 0; }

标签: #c语言如何保存文件到文件夹 #管道c语言 #c语言文件下载 #c语言curl下载文件