c語言中遍歷文件或者文件夾,系統提供的dirent和DIR結構體中包含了文件的很多信息
struct dirent 結構 struct dirent { long d_ino; /* inode number 索引節點號 */ off_t d_off; /* offset to this dirent 在目錄文件中的偏移 */ unsigned short d_reclen; /* length of this d_name 文件名長 */ unsigned char d_type; /* the type of d_name 文件類型 */ char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最長255字符 */ } DIR 結構 struct __dirstream { void *__fd; /* `struct hurd_fd' pointer for descriptor. */ char *__data; /* Directory block. */ int __entry_data; /* Entry number `__data' corresponds to. */ char *__ptr; /* Current pointer into the block. */ int __entry_ptr; /* Entry number `__ptr' corresponds to. */ size_t __allocation; /* Space allocated for the block. */ size_t __size; /* Total valid data in the block. */ __libc_lock_define (, __lock) /* Mutex lock for this structure. */ }; typedef struct __dirstream DIR;
struct dirent中的幾個成員:
d_type:4表示為目錄,8表示為文件
d_reclen:16表示子目錄或文件,24表示非子目錄
經過本人親自試驗發現:d_reclen:16表示子目錄或以.開頭的隱藏文件,24表示普通文本文件,28為二進制文件,等等
d_name:目錄或文件的名稱
具體代碼如下,僅供參考:
#include <stdio.h> #include <dirent.h> #include <sys/stat.h> void List(char *path) { struct dirent* ent = NULL; DIR *pDir; pDir=opendir(path); while (NULL != (ent=readdir(pDir))) { if (ent->d_reclen==24) { if (ent->d_type==8) { printf("普通文件:%s\n", ent->d_name); } else { printf("子目錄:%s\n",ent->d_name); List(ent->d_name); printf("返回%s\n",ent->d_name); } } } } int main(int argc, char *argv[]) { List(argv[1]); return 0; } 上面函數修改后: void List(char *path) { printf("路徑為[%s]\n", path); struct dirent* ent = NULL; DIR *pDir; pDir=opendir(path); //d_reclen:16表示子目錄或以.開頭的隱藏文件,24表示普通文本文件,28為二進制文件,還有其他…… while (NULL != (ent=readdir(pDir))) { printf("reclen=%d type=%d\t", ent->d_reclen, ent->d_type); if (ent->d_reclen==24) { //d_type:4表示為目錄,8表示為文件 if (ent->d_type==8) { printf("普通文件[%s]\n", ent->d_name); } } else if(ent->d_reclen==16) { printf("[.]開頭的子目錄或隱藏文件[%s]\n",ent->d_name); } else { printf("其他文件[%s]\n", ent->d_name); } } }
下面是網上找來的幾個小例子:
#include <stdio.h> #include <dirent.h> #include <sys/types.h> #include <sys/stat.h> void dir_scan(char *path, char *file); int count = 0; int main(int argc, char *argv[]) { struct stat s; if(argc != 2){ printf("one direction requried\n"); exit(1); } if(lstat(argv[1], &s) < 0){ printf("lstat error\n"); exit(2); } //判斷一個路徑是否是目錄 if(!S_ISDIR(s.st_mode)){ printf("%s is not a direction name\n", argv[1]); exit(3); } dir_scan("", argv[1]); printf("total: %d files\n", count); exit(0); } void dir_scan(char *path, char *file) { struct stat s; DIR *dir; struct dirent *dt; char dirname[50]; memset(dirname, 0, 50*sizeof(char)); strcpy(dirname, path); if(lstat(file, &s) < 0){ printf("lstat error\n"); } if(S_ISDIR(s.st_mode)){ strcpy(dirname+strlen(dirname), file); strcpy(dirname+strlen(dirname), "/"); if((dir = opendir(file)) == NULL){ printf("opendir %s/%s error\n"); exit(4); } if(chdir(file) < 0) { printf("chdir error\n"); exit(5); } while((dt = readdir(dir)) != NULL){ if(dt->d_name[0] == '.'){ continue; } dir_scan(dirname, dt->d_name); } if(chdir("..") < 0){ printf("chdir error\n"); exit(6); } }else{ printf("%s%s\n", dirname, file); count++; } } linux c 下如何獲得目錄下的文件數目。 int main(int argc, char **argv) { DIR * pdir; struct dirent * pdirent; struct stat f_ftime; int fcnt;/*文件數目統計*/ pdir=opendir("./"); if(pdir==NULL) { return(-1); } fcnt=0; for(pdirent=readdir(pdir);pdirent!=NULL;pdirent=readdir(pdir)) { if(strcmp(pdirent->d_name,".")==0||strcmp(pdirent->d_name,"..")==0) continue; if(stat(pdirent->d_name,&f_ftime)!=0) return -1 ; if(S_ISDIR(f_ftime.st_mode)) continue; /*子目錄跳過*/ fcnt++; printf("文件:%s\n",pdirent->d_name); } printf("文件總數%d\n",fcnt); closedir(pdir); return 0; } #include <unistd.h> #include <stdio.h> #include <dirent.h> #include <string.h> #include <sys/stat.h> void printdir(char *dir, int depth) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(dir)) == NULL) { fprintf(stderr, "cannot open directory: %s\n ", dir); return; } chdir(dir); while((entry = readdir(dp)) != NULL) { lstat(entry-> d_name,&statbuf); if(S_ISDIR(statbuf.st_mode)) { /**//* Found a directory, but ignore . and .. */ if(strcmp( ". ",entry-> d_name) == 0 || strcmp( ".. ",entry-> d_name) == 0) continue; printf( "%*s%s/\n ",depth, " ",entry-> d_name); /**//* Recurse at a new indent level */ printdir(entry-> d_name,depth+4); } else printf( "%*s%s\n ",depth, " ",entry-> d_name); } chdir( ".. "); closedir(dp); } /**//* Now we move onto the main function. */ int main(int argc, char* argv[]) { char *topdir, pwd[2]= ". "; if (argc != 2) topdir=pwd; else topdir=argv[1]; printf( "Directory scan of %s\n ",topdir); printdir(topdir,0); printf( "done.\n "); exit(0); }
注:關於文件讀取的速度問題
在文件大小相同的前提下:
1.讀剛讀過的文件比頭次讀沒讀過的文件快
2.讀轉速快的硬盤上的文件比讀轉速慢的硬盤上的文件快
3.讀沒有磁盤碎片的文件比讀有磁盤碎片的文件快
4.讀文件不處理比邊讀邊處理快
5.單線程從頭到尾一次讀文件比多線程分別讀文件各部分快(非固態硬盤上)
1.讀剛讀過的文件比頭次讀沒讀過的文件快
2.讀轉速快的硬盤上的文件比讀轉速慢的硬盤上的文件快
3.讀沒有磁盤碎片的文件比讀有磁盤碎片的文件快
4.讀文件不處理比邊讀邊處理快
5.單線程從頭到尾一次讀文件比多線程分別讀文件各部分快(非固態硬盤上)
6.讀固態硬盤上的文件比讀普通硬盤上的文件快
順便提一下在c語言中讀寫文件:
在C語言中寫文件
//獲取文件指針
FILE *pFile = fopen("1.txt", //打開文件的名稱 "w"); // 文件打開方式 如果原來有內容也會銷毀 //向文件寫數據 fwrite ("hello", //要輸入的文字 1,//文字每一項的大小 以為這里是字符型的 就設置為1 如果是漢字就設置為4 strlog("hello"), //單元個數 我們也可以直接寫5 pFile //我們剛剛獲得到的地址 ); //fclose(pFile); //告訴系統我們文件寫完了數據更新,但是我們要要重新打開才能在寫 fflush(pFile); //數據刷新 數據立即更新
在C語言中讀文件
FILE *pFile=fopen("1.txt","r"); //獲取文件的指針 char *pBuf; //定義文件指針 fseek(pFile,0,SEEK_END); //把指針移動到文件的結尾 ,獲取文件長度 int len=ftell(pFile); //獲取文件長度 pBuf=new char[len+1]; //定義數組長度 rewind(pFile); //把指針移動到文件開頭 因為我們一開始把指針移動到結尾,如果不移動回來 會出錯 fread(pBuf,1,len,pFile); //讀文件 pBuf[len]=0; //把讀到的文件最后一位 寫為0 要不然系統會一直尋找到0后才結束 MessageBox(pBuf); //顯示讀到的數據 fclose(pFile); // 關閉文件