当前位置: 首页 > news >正文

Linux实用功能代码集(2) —— 获得机器文件大小和MD5值

在开发中,经常会与文件打交道,而获得文件大小以及MD5值则也是非常常用的功能。下面就给出获取文件大小以及计算其MD5值的代码。

代码如下:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <openssl/md5.h> long get_file_size(const char *file_name) { struct stat file_stat; if (!file_name) { printf("parameter can't be null\n"); return -1; } if (stat(file_name, &file_stat) == -1) { perror("stat failed"); return -1; } return file_stat.st_size; } int get_file_md5(const char *file_name, char *md5_result) { if (!file_name || !md5_result) { printf("parameter can't be null\n"); return -1; } FILE *fp = fopen(file_name, "rb"); if (!fp) { perror("fopen failed"); return -1; } MD5_CTX ctx; MD5_Init(&ctx); unsigned char buf[4096] = {0}; size_t len; while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) MD5_Update(&ctx, buf, len); unsigned char digest[MD5_DIGEST_LENGTH] = {0}; MD5_Final(digest, &ctx); memcpy(md5_result, digest, MD5_DIGEST_LENGTH); fclose(fp); return 0; } int main(int argc, char *argv[]) { if (argc != 2) { printf("usage: %s <file name>\n", argv[0]); return -1; } const char *file_name = argv[1]; struct stat st; if (stat(file_name, &st) == -1) { perror("stat failed"); return -1; } int file_size = st.st_size; printf("file size is: %d bytes\n", file_size); unsigned char md5[16] = {0}; get_file_md5(file_name, md5); for (int i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", md5[i]); printf("\n"); return 0; }

main函数中分为了两部分:获取文件大小,这通过get_file_sizee函数实现;计算文件MD5值,这通过get_file_md5函数实现。

下边依次对这两个函数进行讲解。

1. get_file_size函数

get_file_size函数比较简单,主要就是调用stat函数,让内核填充struct stat file_stat,并且返回file_stat.st_size。

if (stat(file_name, &file_stat) == -1) { perror("stat failed"); return -1; } return file_stat.st_size;

stat函数说明

原型:

#include <sys/stat.h> #include <unistd.h> int stat(const char *pathname, struct stat *statbuf);

参数:

  • const char pathname:文件路径(字符串)。
  • struct stat *statbuf:输出参数,内核把文件信息写入这个结构体。

返回值:

成功返回0;失败返回-1,并且错误码(errno)已正确设置。

struct stat的定义在<sys/stat.h>中,如下:

struct stat { dev_t st_dev; // 文件所在设备号 ino_t st_ino; // inode 号(文件唯一ID) mode_t st_mode; // 文件类型 + 权限 nlink_t st_nlink; // 硬链接数 uid_t st_uid; // 所有者用户ID gid_t st_gid; // 所有者组ID dev_t st_rdev; // 设备号(特殊文件) off_t st_size; // **文件大小(字节)最重要** time_t st_atime; // 最后访问时间 time_t st_mtime; // 最后修改时间 time_t st_ctime; // 最后状态改变时间 };

内核通过此结构体把文件所有信息返回给用户。

除了通过stat系统调用获取文件大小,还可以通过fseek + ftell方式、lseek方式实现相同功能。示例代码如下:

  • fseek + ftell方式
#include <stdio.h> long get_opened_file_size(FILE *fp) { long size; fseek(fp, 0, SEEK_END); // 跳到文件末尾 size = ftell(fp); // 获取当前偏移 = 文件大小 rewind(fp); // 回到文件开头 return size; }
  • lseek方式
#include <unistd.h> long get_fd_file_size(int fd) { return lseek(fd, 0, SEEK_END); }

三种方式比较:

方法优点适用场景
stat()最快、不用打开文件直接获取文件大小(推荐)
fseek() + ftell()标准C,跨平台已用fopen打开文件
lseek()系统调用,速度快已用open打开文件(fd)

2. get_file_md5函数

get_file_md5函数主要基于Linux自带的OpenSSL MD5接口实现。主要步骤为:(1)打开要计算MD5值的文件;(2)分块读取文件(每次4096字节)并计算MD5;(3)生成整个文件的MD5;(4)关闭文件;(5)返回MD5值。

对于OpenSSL MD5相关接口说明如下(内容引自豆包):

注:

1)要使用OpenSSL MD5接口,需要先通过apt安装libssl-dev。

sudo apt install libssl-dev

2)编译的时候必须加入-lcrypto。

对以上代码进行编译,实际命令及结果如下(笔者的环境为VMWare虚拟机,Ubuntu20.04):

$ gcc file_size_md5.c -lcrypto -o get_file_size_md5 $

实际执行结果为:

$ ./get_file_size_md5 file_size_md5.c file size is: 1450 bytes 9430ca7bd6b8148b2725033b4f328762

与通过系统命令ls-l以及md5sum命令得到的结果一致:

$ ls -l file_size_md5.c -rw-rw-r-- 1 habit habit 1450 Mar 21 17:47 file_size_md5.c $ $ md5sum file_size_md5.c 9430ca7bd6b8148b2725033b4f328762 file_size_md5.c

完整工程代码已上传至:

http://www.jsqmd.com/news/517537/

相关文章:

  • MCP/A2A/Agent Skills引爆智能体互联网时代!
  • 高效UI自动化测试的基石:FlaUInspect的核心功能解析与实践指南
  • 最讽刺的是附语
  • 医学论文降AI率哪个好?临床/护理/药学论文专用方案 - 我要发一区
  • 气象数据可视化大屏:如何用动态交互提升天气信息呈现效果
  • 聊聊凡思蔓全铝定制评价如何,其在北京市场的性价比靠谱吗? - myqiye
  • CLAP模型与LaTeX结合:自动化生成音频分析报告
  • 理工科论文降AI率用什么好?计算机/电子/机械等学科实测分享 - 我要发一区
  • 盘点株洲铭聚汇在行业内的口碑地位,它与其他财务公司对比咋样? - mypinpai
  • LLM微调实战:LoRA、QLoRA、RLHF、DPO、GRPO技术全解析,代码示例助你轻松掌握!
  • 现浇混凝土施工,口碑好的公司具备这些特点,现浇保温层/现浇阳台/现浇阁楼/现浇钢筋混凝土,现浇混凝土公司有哪些分析 - 品牌推荐师
  • 冰雪奇缘主题生日视频一键生成指南,3分钟打造专属魔法祝福(含免费素材包)
  • 支持AI智能分析的大中型企业CRM系统推荐(2026最新版) - SaaS软件-点评
  • 2026年大模型从入门到精通:这份学习路线图助你成为行业精英!AI大模型应用开发学习路线(2026最新)
  • CRM 系统有哪些核心功能?一文看懂全模块能力 - SaaS软件-点评
  • FastHook框架深度解析:从EntryPoint替换到微信Hook实战(支持Android 5-9)
  • 发射1w个子弹和Mono世界交互——影子Dots碰撞系统
  • 低配置电脑福音:MPC-HC轻量化设计与资源优化策略研究
  • 手把手教你用虹科转换器搭建车载以太网测试环境(含MATEnet接口避坑)
  • 双MCU架构下的汽车ECU硬件电路设计关键点解析
  • 贵州维恒琦科技客服咨询AI流量赋能,重塑智能体验新标杆 - 速递信息
  • 2026年铝型材价格对比,南昌铝型材精品定制哪家性价比高 - 工业品网
  • 2026年高铁驱鸟器口碑排名,看看哪家更值得选 - 工业品牌热点
  • Anolis OS7.9_x86服务器部署避坑指南:PostgreSQL+PostGIS+PgRouting地理数据库配置详解
  • SQL也能玩转机器学习?教你用PostgreSQL内置ML引擎完成用户画像分析
  • 从USB摄像头到RTSP推流:基于RK3588 MPP硬编码的YOLOv8实时AI视觉方案
  • Seed_Ultrasonic_Range驱动库深度解析:HC-SR04超声波测距的嵌入式实现
  • 告别云端API调用!手把手教你用Ollama+AnythingLLM在Windows/Mac上搭建个人DeepSeek知识库
  • 2026年驻马店靠谱玻璃贴膜公司有哪些,怎么选择 - 工业设备
  • 深入解析Linux内核中的workqueue机制与queue_work实现