zoukankan      html  css  js  c++  java
  • 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.单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
     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); // 关闭文件
  • 相关阅读:
    React-Native到0.44版本后Navigator 不能用的问题
    php基础
    数据库学习内容复习
    数据库常用的函数
    45道题 数据库的
    数据库里any 和 all 的区别
    高级查询
    表中添加列,删除列,修改列名字
    创建,读取,修改,删除表 简单查询 12种
    设计表:多张表存储学生成绩及各种信息
  • 原文地址:https://www.cnblogs.com/cocoabird/p/5987421.html
Copyright © 2011-2022 走看看