目錄
🍅點擊這里查看所有博文
??隨著自己工作的進行,接觸到的技術棧也越來越多。給我一個很直觀的感受就是,某一項技術/經驗在剛開始接觸的時候都記得很清楚。往往過了幾個月都會忘記的差不多了,只有經常會用到的東西才有可能真正記下來。存在很多在特殊情況下有一點用處的技巧,用的不多的技巧可能一個星期就忘了。
??想了很久想通過一些手段把這些事情記錄下來。也嘗試過在書上記筆記,這也只是一時的,書不在手邊的時候那些筆記就和沒記一樣,不是很方便。
??很多時候我們遇到了問題,一般情況下都是選擇在搜索引擎檢索相關內容,這樣來的也更快一點,除非真的找不到才會去選擇翻書。后來就想到了寫博客,博客作為自己的一個筆記平臺倒是挺合適的。隨時可以查閱,不用隨身攜帶。
??同時由于寫博客是對外的,既然是對外的就不能隨便寫,任何人都可以看到。經驗對于我來說那就只是經驗而已,公布出來說不一定我的一些經驗可以幫助到其他的人。遇到和我相同問題時可以少走一些彎路。
??既然決定了要寫博客,那就只能認真去寫。不管寫的好不好,盡力就行。千里之行始于足下,一步一個腳印,慢慢來
,寫的多了慢慢也會變好的。權當是記錄自己的成長的一個過程,等到以后再往回看時,就會發現自己以前原來這么菜😂。
??本系列博客所述資料均來自互聯網
,并不是本人原創(只有博客是自己寫的)。出于熱心,本人將自己的所學筆記整理并推出相對應的使用教程,方面其他人學習。為國內的物聯網事業發展盡自己的一份綿薄之力,沒有為自己謀取私利的想法
。若出現侵權現象,請告知本人,本人會立即停止更新,并刪除相應的文章和代碼。
遍歷排序目錄
??代碼片段中,對指定目錄遍歷。并存入到指定數組中,隨后對文件名進行排序。按照順序計算所有非空文件的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;
}
??那么本篇博客就到此結束了,這里只是記錄了一些我個人的學習筆記,其中存在大量我自己的理解。文中所述不一定是完全正確的,可能有的地方我自己也理解錯了。如果有些錯的地方,歡迎大家批評指正。如有問題直接在對應的博客評論區指出即可,不需要私聊我。我們交流的內容留下來也有助于其他人查看,說不一定也有其他人遇到了同樣的問題呢😂。