curl 库 CURLINFO_SIZE_UPLOAD_T 完全指南:精确统计上传字节数
curl 库 CURLINFO_SIZE_UPLOAD_T 完全指南精确统计上传字节数【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl导读CURLINFO_SIZE_UPLOAD_T是 libcurl 提供的运行时统计接口用于在请求完成后读取本次传输实际上传的总字节数。它在 curl 项目GitHub_Trending/cu/curl中广泛应用于进度展示、限速与断点续传等场景——无论是用curl_easy_perform完成的一次性上传还是基于curl_multi的并发上传任务都能通过它拿到精确的curl_off_t类型计数。读完本文你将掌握该选项的完整用法、与旧版CURLINFO_SIZE_UPLOAD的区别、底层数据来源以及如何在真实代码中正确获取与格式化上传字节数。接口速览函数原型#include curl/curl.h CURLcode curl_easy_getinfo(CURL *handle, CURLINFO_SIZE_UPLOAD_T, curl_off_t *uploadp);handle已初始化并完成一次curl_easy_perform或 multi 接口驱动传输的 easy handle。uploadp指向curl_off_t的指针函数执行成功后此处写入本次传输累计上传的字节总数。返回值CURLcode状态码CURLE_OK表示成功非零表示出错具体错误参见 libcurl-errors。类型定义头文件中的枚举值在 include/curl/curl.h 中可以看到该选项在CURLINFO枚举中的定义CURLINFO_SIZE_UPLOAD CURL_DEPRECATED(7.55.0, Use CURLINFO_SIZE_UPLOAD_T) CURLINFO_DOUBLE 7, CURLINFO_SIZE_UPLOAD_T CURLINFO_OFF_T 7,其中CURLINFO_OFF_T0x600000是 64 位有符号整数类型的标记位CURLINFO_DOUBLE0x300000是双精度浮点标记位。这从编译期就决定了新旧两个选项的输出数据类型不同旧版CURLINFO_SIZE_UPLOAD返回double新版CURLINFO_SIZE_UPLOAD_T返回curl_off_t。CURL_DEPRECATED(7.55.0, ...)宏表明旧接口自 7.55.0 起被标记为废弃官方建议一律改用_T后缀版本。基本用法读取上传字节数以下代码完整演示了获取上传字节数的标准流程示例同时用于 PUT/POST 等上传场景#include stdio.h #include curl/curl.h int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; curl_easy_setopt(curl, CURLOPT_URL, https://example.com); /* Perform the request */ result curl_easy_perform(curl); if(result CURLE_OK) { curl_off_t ul; result curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, ul); if(result CURLE_OK) { printf(Uploaded % CURL_FORMAT_CURL_OFF_T bytes\n, ul); } } curl_easy_cleanup(curl); } return 0; }要点说明调用时机必须在该 easy handle 完成传输之后例如curl_easy_perform返回之后调用否则读到的仍是上一次或未初始化的值。在 multi 接口中应在CURLMSG_DONE消息回调或curl_multi_info_read返回该 transfer 完成状态之后再查询。返回值检查curl_easy_getinfo的返回值同样需要检查即使perform成功getinfo 也可能因参数类型不匹配等原因返回错误。类型与格式化curl_off_t通常是 64 位有符号整数不能直接用%d/%ld打印不同平台宽度可能不同应使用头文件提供的CURL_FORMAT_CURL_OFF_T格式化宏以保证可移植性。计数语义统计的是“实际上传”的字节数即写入协议的数据量对 HTTP 而言包括请求体如 PUT/POST 的 body等上行数据但不包括协议头header部分。该值遵循CURLINFO_OFF_T类型可表示超大文件的上传量而不受double精度损失影响。与 CURLINFO_SIZE_UPLOAD旧版的对比对比项CURLINFO_SIZE_UPLOAD废弃CURLINFO_SIZE_UPLOAD_T推荐引入版本7.4.17.55.0输出类型double *curl_off_t *精度大数如超过 2^53 字节存在精度损失64 位整数无损状态自 7.55.0 起CURL_DEPRECATED当前推荐接口旧版定义参见 docs/libcurl/opts/CURLINFO_SIZE_UPLOAD.md其内部实现*param_doublep (double)data-progress.ul.cur_size;见 lib/getinfo.c会将 64 位计数强转成double当上传量超过double精确表示范围约 9 PB时不再精确新版则直接返回data-progress.ul.cur_size的原始curl_off_t值见 lib/getinfo.c。因此凡是上传量可能很大的场景都应使用_T版本。底层实现数据从哪来CURLINFO_SIZE_UPLOAD_T不是独立维护的计数器而是直接读取 easy handle 内部进度结构体struct Progress中上传方向的累计值。整个数据链路如下存储位置struct Progress内包含上传方向统计子结构struct pgrs_dir ul其成员cur_size即“已传输字节数”见 lib/urldata.hstruct pgrs_dir { curl_off_t total_size; /* total expected bytes */ curl_off_t cur_size; /* transferred bytes so far */ curl_off_t speed; /* bytes per second transferred */ struct Curl_rlimit rlimit; /* speed limiting / pausing */ };计数累加传输过程中各协议过滤器filter每写出delta字节都会调用进度模块的Curl_pgrs_upload_inc()将data-progress.ul.cur_size delta见 lib/progress.c另有Curl_pgrsSetUploadCounter()用于直接设置当前上传计数值见 lib/progress.c。读取返回curl_easy_getinfo内部在CURLINFO_SIZE_UPLOAD_T分支直接返回*param_offt >curl_off_t sent, expected; curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD_T, sent); curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_UPLOAD_T, expected); if(expected 0 sent ! expected) fprintf(stderr, Upload incomplete: % CURL_FORMAT_CURL_OFF_T of % CURL_FORMAT_CURL_OFF_T bytes\n, sent, expected);2. 配合上传选项使用CURLINFO_SIZE_UPLOAD_T通常与以下上传相关选项配合构成完整的上传流程CURLOPT_UPLOAD开启上传模式如 FTP 上传、HTTP PUT。CURLOPT_POSTFIELDS/CURLOPT_POSTFIELDSIZE/CURLOPT_POSTFIELDSIZE_LARGE指定 POST 数据及长度_LARGE版本使用curl_off_t与本文类型一致。CURLOPT_READFUNCTION与CURLOPT_READDATA自定义上传数据读取回调。CURLOPT_INFILESIZE_LARGE告知服务器上传文件大小。CURLOPT_RESUME_FROM_LARGE断点续传偏移配合续传完成后用本选项核对已传总量。各选项的详细说明见 docs/libcurl/opts 目录例如CURLOPT_UPLOAD.md、CURLOPT_INFILESIZE_LARGE.md。3. 在 multi 接口中统计并发上传在多句柄并发场景下每个 easy handle 独立维护自己的ul.cur_size因此可在每个 transfer 完成CURLMSG_DONE后分别查询再汇总得到整体上传量互不干扰。注意事项与易错点必须在传输完成后读取传输进行中读取可能得到 0 或中间值重用一个 easy handle 发起第二次传输前值会在新传输初始化时被清零见 lib/progress.c。类型必须匹配_T版本必须传入curl_off_t *旧版必须传入double *。混用会导致内存越界写入类型大小不同属于未定义行为。统计范围是“已发送的应用数据”不包含协议头对分块传输chunked等场景计数的是 payload 字节。旧版精度问题不要在新代码中使用CURLINFO_SIZE_UPLOAD即使旧代码也建议迁移到_T版本。版本要求该接口自 libcurl 7.55.0 引入见文档头部Added-in: 7.55.0字段使用前需确认链接的 libcurl 版本满足要求。小结CURLINFO_SIZE_UPLOAD_T是 libcurl 获取上传字节数的事实标准接口它以 64 位整数精确返回每次传输的上传总量底层直接读取进度模块ul.cur_size计数器与速率、长度等_T系列接口协同可完整刻画上传过程。在实践中记住三点即可用得准确传输完成后查询、传curl_off_t *、用CURL_FORMAT_CURL_OFF_T打印。更多细节可参考 docs/libcurl/opts/CURLINFO_SIZE_UPLOAD_T.md 与配套的 curl_easy_getinfo 文档。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考