Chinaunix首页 | 论坛 | 博客
  • 博客访问: 425766
  • 博文数量: 126
  • 博客积分: 35
  • 博客等级: 民兵
  • 技术积分: 1262
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 16:39
文章分类

全部博文(126)

文章存档

2017年(2)

2016年(20)

2015年(64)

2014年(24)

2013年(16)

我的朋友

分类: C/C++

2015-01-26 16:16:42

参考帖子:


1楼、5楼:是按照d_off 来排序的,readdir的排列循序是按照在磁盘上的索引顺序读上来的,所以必须自己排序

   struct dirent
              {
                  long d_ino;                 /* inode number */
                  off_t d_off;                /* offset to this dirent */
                  unsigned short d_reclen;    /* length of this d_name */
                  char d_name [NAME_MAX+1];   /* filename (null-terminated) */
              }

d_ino  is an inode number.  d_off is the distance from the start of the directory to this dirent.  d_reclen is the size
       of d_name, not counting the null terminator.  d_name is a null-terminated filename.


是按照d_off 来排序的, 我写了个小程序作测试。

  1. #include<sys/types.h>
  2. #include<stdio.h>
  3. #include<dirent.h>
  4. #include<unistd.h>
  5. main()
  6. {
  7.   DIR *dir;
  8.   struct dirent *ptr;
  9.   int i;
  10.  
  11.   dir =opendir(".");
  12.  
  13.   while((ptr = readdir(dir))!=NULL)
  14.   {
  15.          printf(" d_off:%d d_name: %s\n", ptr->d_off,ptr->d_name);
  16.   }
  17.         closedir(dir);
  18. }
所以需要自己取排列循序

scandir函数,参考帖子:
http://www.cppblog.com/mysileng/archive/2013/01/02/196904.html


首先看一下man的scandir 接口定义
int scandir(const char *dir, struct dirent ***namelist,
              int(*filter)(const struct dirent *),
              int(*compar)(const struct dirent **, const struct dirent **));
,从定义来看就不是一个简单的函数,形参里,出现一个三级指针,二个函数指针。它的功能是,扫描名字为dir的目录,把满足filter函数的过滤条件(即filter执行为非0值)的目录项加入到一维指针数组namelist.数组的总长度为返回值n,如果compar不为空,则最终输出结果还要调用qsort来对数组进行排序后再输出。
 
从scandir的演示代码,我们可以推算出namelist是一个指向一维指针数组的指针。(一维指针数组等同于 struct dirent ** namelist,这里写在三级指针是因为要从函数里改变namelist的值,必须再多做一级)原因可以参考我的函数传值类型的说明。
 
以下是一个简单扫描 /usr/lib,并且把所有以lib打头的文件扫描到namelist数组的测试程序,这是参考scandir 提供的样例来修改,alphasort是做原始的ASCII码值比较进行排序的
 
可以看到namelist是完全动态分配的,不仅数组本身是动态分配,而且数组项指向的空间也是动态分配的。
 
 

#include <sys/types.h>
#include <dirent.h>

#include <sys/stat.h>
#include <unistd.h>

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

//扫描所有的lib打头的文件

 int filter_fn(const struct dirent * ent)
 {
   if(ent->d_type != DT_REG)
     return 0;
     
   return (strncmp(ent->d_name,"lib",3) == 0);
 }


void scan_lib(char * dir_name)
{
  int n;
   struct dirent **namelist; // struct dirent * namelist[];

   n = scandir(dir_name, &namelist, filter_fn, alphasort);
   if (< 0)
        perror("scandir");
   else {
               while(n--) {
                   printf("%s\n", namelist[n]->d_name);
                   free(namelist[n]);
               }
               free(namelist);
           }
}

int main(int argc ,char * argv[])
{
   scan_lib("/usr/lib"); 
}




阅读(8353) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~