10、杂项:遍历指定目录计算文件的md5并输出到文件

目录

🍅点击这里查看所有博文

  随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有一点用处的技巧,用的不多的技巧可能一个星期就忘了。

  想了很久想通过一些手段把这些事情记录下来。也尝试过在书上记笔记,这也只是一时的,书不在手边的时候那些笔记就和没记一样,不是很方便。

  很多时候我们遇到了问题,一般情况下都是选择在搜索引擎检索相关内容,这样来的也更快一点,除非真的找不到才会去选择翻书。后来就想到了写博客,博客作为自己的一个笔记平台倒是挺合适的。随时可以查阅,不用随身携带。

  同时由于写博客是对外的,既然是对外的就不能随便写,任何人都可以看到。经验对于我来说那就只是经验而已,公布出来说不一定我的一些经验可以帮助到其他的人。遇到和我相同问题时可以少走一些弯路。

  既然决定了要写博客,那就只能认真去写。不管写的好不好,尽力就行。千里之行始于足下,一步一个脚印,慢慢来 ,写的多了慢慢也会变好的。权当是记录自己的成长的一个过程,等到以后再往回看时,就会发现自己以前原来这么菜😂。

  本系列博客所述资料均来自互联网,并不是本人原创(只有博客是自己写的)。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。

遍历排序目录

  代码片段中,对指定目录遍历。并存入到指定数组中,随后对文件名进行排序。按照顺序计算所有非空文件的md5值。

// 比较函数,用于排序
static int compare(const void *a, const void *b) {return strcmp(*(const char **)a, *(const char **)b);
}
static void dirfiles_md5sum(const char *dirname, const char *autofile) {DIR *dir;struct dirent *entry;int count = 0;char **files;dir = opendir(dirname);if (dir == NULL) {printf("Unable to open directory:%s", dirname);return;}// 统计目录中的文件和子目录数量while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {count++;}}// 分配内存files = (char **)malloc(count * sizeof(char *));if (files == NULL) {printf("malloc fail\n");closedir(dir);return;}// 重新遍历目录,并将文件名存储到数组中rewinddir(dir);count = 0;char path[128] = {0};while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);files[count] = strdup(path);count++;}}// 对文件名进行排序qsort(files, count, sizeof(char *), compare);// 遍历排序后的数组并输出文件名for (int i = 0; i < count; i++) {// 判断当前文件名是否为目录DIR *subdir = opendir(files[i]);if (subdir != NULL) {closedir(subdir);// 递归遍历子目录dirfiles_md5sum(files[i], autofile);}else{char *filename = files[i];FILE *file_handle = fopen(filename, "r");if (file_handle == NULL) {printf("Unable to open file:%s", filename);free(files[i]);continue;}// 读取一个字符,判断文件是否为空if (fgetc(file_handle) != EOF) {char md5sum[256] = {0};calculate_md5(filename, md5sum, sizeof(md5sum));append_line(autofile, md5sum);}fclose(file_handle);}free(files[i]);}// 释放内存并关闭目录free(files);closedir(dir);
}

遍历排序目录

  代码片段对传入的文件进行md5运算,并输出结果。通过popen调用系统命令md5sum用以计算md5值。该方法更简单一些,不需要移植open-ssl。

static int calculate_md5(const char *filename, char *md5sum, int md5sum_len) 
{FILE *fp = NULL;char check_md5_cmd[128] = { 0 };sprintf(check_md5_cmd, "md5sum %s", filename);fp = popen(check_md5_cmd, "r");if(!fp) {printf("md5sum calculation failed.");return -1;}if(NULL == fgets(md5sum, md5sum_len, fp)) {printf("can not get first md5sum");pclose(fp);return -1;}pclose(fp);printf("md5sum:%s",md5sum);return 0;
}

输出到指定目录

  以插入的方式(a)打开文件,直接写入即可。

static void append_line(const char *filename, const char *new_line) 
{    // 打开文件,以追加模式打开(如果文件不存在则创建)FILE *file = fopen(filename, "a");if (file == NULL) {printf("Unable to open file:%s", filename);return;}// 将新行写入文件fprintf(file, "%s", new_line);// 关闭文件fclose(file);
}

完整代码

#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>#define FIREWARE_MODEM_MD5_FIEL "./md5sum.txt"static void append_line(const char *filename, const char *new_line) 
{    // 打开文件,以追加模式打开(如果文件不存在则创建)FILE *file = fopen(filename, "a");if (file == NULL) {printf("Unable to open file:%s", filename);return;}// 将新行写入文件fprintf(file, "%s", new_line);// 关闭文件fclose(file);
}
static int calculate_md5(const char *filename, char *md5sum, int md5sum_len) 
{FILE *fp = NULL;char check_md5_cmd[128] = { 0 };sprintf(check_md5_cmd, "md5sum %s", filename);fp = popen(check_md5_cmd, "r");if(!fp) {printf("md5sum calculation failed.");return -1;}if(NULL == fgets(md5sum, md5sum_len, fp)) {printf("can not get first md5sum");pclose(fp);return -1;}pclose(fp);printf("md5sum:%s",md5sum);return 0;
}
// 比较函数,用于排序
static int compare(const void *a, const void *b) {return strcmp(*(const char **)a, *(const char **)b);
}
static void dirfiles_md5sum(const char *dirname, const char *autofile) {DIR *dir;struct dirent *entry;int count = 0;char **files;dir = opendir(dirname);if (dir == NULL) {printf("Unable to open directory:%s", dirname);return;}// 统计目录中的文件和子目录数量while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {count++;}}// 分配内存files = (char **)malloc(count * sizeof(char *));if (files == NULL) {printf("malloc fail\n");closedir(dir);return;}// 重新遍历目录,并将文件名存储到数组中rewinddir(dir);count = 0;char path[128] = {0};while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);files[count] = strdup(path);count++;}}// 对文件名进行排序qsort(files, count, sizeof(char *), compare);// 遍历排序后的数组并输出文件名for (int i = 0; i < count; i++) {// 判断当前文件名是否为目录DIR *subdir = opendir(files[i]);if (subdir != NULL) {closedir(subdir);// 递归遍历子目录dirfiles_md5sum(files[i], autofile);}else{char *filename = files[i];FILE *file_handle = fopen(filename, "r");if (file_handle == NULL) {printf("Unable to open file:%s", filename);free(files[i]);continue;}// 读取一个字符,判断文件是否为空if (fgetc(file_handle) != EOF) {char md5sum[256] = {0};calculate_md5(filename, md5sum, sizeof(md5sum));append_line(autofile, md5sum);}fclose(file_handle);}free(files[i]);}// 释放内存并关闭目录free(files);closedir(dir);
}int main(void) {dirfiles_md5sum("./firmware",FIREWARE_MODEM_MD5_FIEL);return 0;
}

  那么本篇博客就到此结束了,这里只是记录了一些我个人的学习笔记,其中存在大量我自己的理解。文中所述不一定是完全正确的,可能有的地方我自己也理解错了。如果有些错的地方,欢迎大家批评指正。如有问题直接在对应的博客评论区指出即可,不需要私聊我。我们交流的内容留下来也有助于其他人查看,说不一定也有其他人遇到了同样的问题呢😂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/35781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Rust】Rust学习 第十一章编写自动化测试

Rust 是一个相当注重正确性的编程语言&#xff0c;不过正确性是一个难以证明的复杂主题。Rust 的类型系统在此问题上下了很大的功夫&#xff0c;不过它不可能捕获所有种类的错误。为此&#xff0c;Rust 也在语言本身包含了编写软件测试的支持。 编写一个叫做 add_two 的将传递…

[C++ 网络协议编程] TCP/IP协议

目录 1. TCP/IP协议栈 2. TCP原理 2.1 TCP套接字中的I/O缓冲 2.2 TCP工作原理 2.2.1 三次握手&#xff08;连接&#xff09; 2.2.2 与对方主机的数据交换 2.2.3 四次握手&#xff08;断开与套接字的连接&#xff09; TCP&#xff08;Transmission Control Protocol传输控…

无涯教程-Perl - ref函数

描述 如果EXPR为引用,则此函数返回真值&#xff1b;如果未提供EXPR,则为$_。返回的实际值还定义了引用所引用的实体的类型。 内置类型为- REFSCALARARRAYHASHCODEGLOBLVALUEIO::Handle 如果使用bless()函数为变量设置了祝福,则将返回新的数据类型。新的数据类型通常将是一个…

比较编程语言C和Go

使用一个简单的计数程序来比较古老的C语言和现代的Go语言。Go是一种现代的编程语言&#xff0c;它在很大程度上源自C语言。因此&#xff0c;对于任何使用C语言编写程序的人来说&#xff0c;Go可能会感觉很熟悉。Go使得编写新程序变得容易&#xff0c;同时又让C程序员感到熟悉&a…

大数据-玩转数据-Flink 自定义Sink(Mysql)

一、说明 如果Flink没有提供给我们可以直接使用的连接器&#xff0c;那我们如果想将数据存储到我们自己的存储设备中&#xff0c;mysql 的安装使用请参考 mysql-玩转数据-centos7下mysql的安装 创建表 CREATE TABLE sensor (id int(10) ) ENGINEInnoDB DEFAULT CHARSETutf8二…

二 根据用户行为数据创建ALS模型并召回商品

二 根据用户行为数据创建ALS模型并召回商品 2.0 用户行为数据拆分 方便练习可以对数据做拆分处理 pandas的数据分批读取 chunk 厚厚的一块 相当大的数量或部分 import pandas as pd reader pd.read_csv(behavior_log.csv,chunksize100,iteratorTrue) count 0; for chunk in …

DNS协议及其工作原理

DNS是域名系统&#xff08;Domain Name System&#xff09;的缩写&#xff0c;它是一种用于将域名转换为IP地址的分布式数据库系统。它是因特网的基石&#xff0c;能够使人们通过域名方便地访问互联网&#xff0c;而无需记住复杂的IP地址。 DNS的历史可以追溯到1983年&#xf…

4个简化IT服务台任务的ChatGPT功能

最近几个月&#xff0c;ChatGPT 风靡全球&#xff0c;这是一个 AI 聊天机器人&#xff0c;使用户能够生成脚本、文章、锻炼图表等。这项技术在各行各业都有无穷无尽的应用&#xff0c;在本文中&#xff0c;我们将研究这种现代技术如何帮助服务台团队增强服务交付和客户体验。 什…

最佳实践:如何优雅地提交一个 Amazon EMR Serverless 作业?

《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书由博主历时三年精心创作&#xff0c;现已通过知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详…

章节7:XSS检测和利用

章节7&#xff1a;XSS检测和利用 测试payload <script>alert(XSS)</script> <script>alert(document.cookie)</script> ><script>alert(document.cookie)</script> ><script>alert(document.cookie)</script> &qu…

元宇宙之经济(02)理解NFT

1 NFT是什么&#xff1f; 想象一下&#xff0c;你小时候曾经在操场上集齐过各种不同的贴纸&#xff0c;然后和朋友们交换&#xff0c;这些贴纸有着独特的图案和价值。NFT的概念与此类似&#xff0c;但在数字世界中运作。NFT是一种基于区块链技术的数字资产&#xff0c;每个NFT…

golang—面试题大全

目录标题 sliceslice和array的区别slice扩容机制slice是否线程安全slice分配到栈上还是堆上扩容过程中是否重新写入go深拷贝发生在什么情况下&#xff1f;切片的深拷贝是怎么做的copy和左值进行初始化区别slice和map的区别 mapmap介绍map的key的类型map对象如何比较map的底层原…

《Java极简设计模式》第03章:工厂方法模式(FactoryMethod)

作者&#xff1a;冰河 星球&#xff1a;http://m6z.cn/6aeFbs 博客&#xff1a;https://binghe.gitcode.host 文章汇总&#xff1a;https://binghe.gitcode.host/md/all/all.html 源码地址&#xff1a;https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

无法正确识别车牌(Python、OpenCv、Tesseract)

我正在尝试识别车牌&#xff0c;但出现了错误&#xff0c;例如错误/未读取字符 以下是每个步骤的可视化&#xff1a; 从颜色阈值变形关闭获得遮罩 以绿色突出显示的车牌轮廓过滤器 将板轮廓粘贴到空白遮罩上 Tesseract OCR的预期结果 BP 1309 GD 但我得到的结果是 BP 1309…

腾讯云标准型CVM云服务器详细介绍

腾讯云CVM服务器标准型实例的各项性能参数平衡&#xff0c;标准型云服务器适用于大多数常规业务&#xff0c;例如&#xff1a;web网站及中间件等&#xff0c;常见的标准型云服务器有CVM标准型S5、S6、SA3、SR1、S5se等规格&#xff0c;腾讯云服务器网来详细说下云服务器CVM标准…

NAS搭建指南一——服务器的选择与搭建

一、服务器的选择 有自己的本地的公网 IP 的请跳过此篇文章按需求选择一个云服务器&#xff0c;目的就是为了进行 frp 的搭建&#xff0c;完成内网穿透我选择的是腾讯云服务器&#xff0c;我的配置如下&#xff0c;仅供参考&#xff1a; 4. 腾讯云服务器官网地址 二、服务器…

docker 镜像的导出与导入 save 与 load

一、镜像导出 docker save 导出 将系统中的镜像保存为压缩包&#xff0c;进行文件传输。使用 docker save --help 查看命令各参数&#xff0c;或者去docker官网查看.以 hello-world镜像为例。 A&#xff1a;将镜像保存为tar包 docker save image > package.tar docker sa…

day9 10-牛客67道剑指offer-JZ66、19、20、75、23、76、8、28、77、78

文章目录 1. JZ66 构建乘积数组暴力解法双向遍历 2. JZ19 正则表达式匹配3. JZ20 表示数值的字符串有限状态机遍历 4. JZ75 字符流中第一个不重复的字符5. JZ23 链表中环的入口结点快慢指针哈希表 6. JZ76 删除链表中重复的结点快慢指针三指针如果只保留一个重复结点 7. JZ8 二…

gitblit-使用

1.登入GitBlit服务器 默认用户和密码: admin/admin 2.创建一个新的版本库 点击图中的“版本库”&#xff0c;然后点击图中“创建版本库” 填写名称和描述&#xff0c;注意名称最后一定要加 .git选择限制查看、克隆和推送勾选“加入README”和“加入.gitignore文件”在图中的1处…

使用IIS服务器部署Flask python Web项目

参考文章 ""D:\Program Files (x86)\Python310\python310.exe"|"D:\Program Files (x86)\Python310\lib\site-packages\wfastcgi.py"" can now be used as a FastCGI script processor参考文章 请求路径填写*&#xff0c;模块选择FastCgiModule&…