首页 > 代码库 > C语言文件遍历及读写
C语言文件遍历及读写
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); // 关闭文件
C语言文件遍历及读写
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。