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.pswp.cn/news/35781.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/35781.shtml
英文地址,請注明出處:http://en.pswp.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&…