linux下目录扫描的实现

来源:互联网 发布:用户画像数据建模方法 编辑:程序博客网 时间:2024/05/16 15:46

项目中实现了一个目录扫描的函数

 

#include <stdio.h>
#include <dirent.h>
#include <string.h>

int dir_scan(char *dir);

int main(int argc, char **argv)
{
 if(argc != 2){
  printf("input the dir which is to be scanned!/n");
  return 1;
 }

 dir_scan(argv[1]);

 return 0; 
}

int dir_scan(char *dir)
{
 DIR *dp;
 struct dirent *entry;
 char buf[256];

 if((dp = opendir(dir)) == NULL){
  fprintf(stderr, "cannot open directory: %s/n", dir);
  return 1;
 }

 while((entry = readdir(dp)) != NULL){
  if(entry->d_type == DT_DIR){
   /*found a directory ,but ignore . and ..*/
   if(!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name))
    continue;
   bzero(buf, sizeof(buf));
   snprintf(buf, 255, "%s/%s", dir, entry->d_name);
   /*recurse to scan the sub directory*/
   dir_scan(buf);
  } 
  else{    
   printf("fullfilename:%s/%s/n", dir, entry->d_name);
  }
 }

 closedir(dp);

 return 0;
}

 

 

后来使用多线程,因为readdir并非是线程安全的,所以改用readdir_r重新实现如下:

 

int dir_scan(char *dir)
{
 DIR *dp;
 struct dirent entry;
 struct dirent *entryPtr;
 char buf[256];
 int retval = 0;

 if((dp = opendir(dir)) == NULL){
  fprintf(stderr, "cannot open directory: %s/n", dir);
  return 1;
 }

 retval = readdir_r(dp, &entry, &entryPtr);
 while(entryPtr != NULL){
  if(entry.d_type == DT_DIR){
   /*found a directory ,but ignore . and ..*/
   if(!strcmp(".", entry.d_name) || !strcmp("..", entry.d_name)){
    retval = readdir_r(dp, &entry, &entryPtr);
    continue;}
    
   
   bzero(buf, sizeof(buf));
   snprintf(buf, 255, "%s/%s", dir, entry.d_name);
   /*recurse to scan the sub directory*/
   dir_scan(buf);
   
   retval = readdir_r(dp, &entry, &entryPtr);   
  }
  else{
   printf("fullfilename:%s/%s/n", dir, entry.d_name);
   retval = readdir_r(dp, &entry, &entryPtr);
  }
  
 }

 closedir(dp);

 return 0;
}

 

 

但是程序当中采用了snprintf()函数,此函数也非线程安全的,此时可以使用vsnprintf(),来代替snprintf()

http://www.ibm.com/developerworks/cn/aix/library/0806_xiazq_thread/index.html

中提到“snprintf(), vsprintf() 都可以说是线程安全的。存在一种例外情况就是,当这些函数执行的时候,如果有其它线程调用 setlocale 函数,那么可能会出现不安全的可能。不过我们通常不会轻易设置 locale 的值

 

以下用vsnprintf()来代替snprintf()

 

 

#include <stdio.h>
#include <stdarg.h>


int vspf(char *buf, int bufsize, char *fmt, ...)

 va_list argptr;
 int cnt;
 va_start(argptr, fmt);
 cnt = vsnprintf(buf, bufsize ,fmt, argptr);
 va_end(argptr);
 return(cnt);
}

 

 

此时可以用函数vspf()来代替snprintf(), 参数完全相同

 

 

int dir_scan(char *dir)
{
 DIR *dp;
 struct dirent entry;
 struct dirent *entryPtr;
 char buf[256];
 int retval = 0;

 if((dp = opendir(dir)) == NULL){
  fprintf(stderr, "cannot open directory: %s/n", dir);
  return 1;
 }

 retval = readdir_r(dp, &entry, &entryPtr);
 while(entryPtr != NULL){
  if(entry.d_type == DT_DIR){
   /*found a directory ,but ignore . and ..*/
   if(!strcmp(".", entry.d_name) || !strcmp("..", entry.d_name)){
    retval = readdir_r(dp, &entry, &entryPtr);
    continue;}
    
   
   bzero(buf, sizeof(buf));

 

   //snprintf(buf, 255, "%s/%s", dir, entry.d_name);

   vspf(buf, 255, "%s/%s", dir, entry.d_name);


   /*recurse to scan the sub directory*/
   dir_scan(buf);
   
   retval = readdir_r(dp, &entry, &entryPtr);   
  }
  else{
   printf("fullfilename:%s/%s/n", dir, entry.d_name);
   retval = readdir_r(dp, &entry, &entryPtr);
  }
  
 }

 closedir(dp);

 return 0;
}

 

多线程还真是个麻烦的主儿~

原创粉丝点击