递归遍历一个文件夹,对文件进行操作,使用lstat时的悲剧

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>

#include <iostream>
#include <fstream>

using namespace std;


int processDirectory(char * dir,FILE * pWFile)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    long lSize;
    size_t result;

    int i,j;    


    if((dp = opendir(dir)) == NULL){
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return -1 ;
    }
        
        chdir(dir);
    while((entry = readdir(dp)) != NULL)
    {
        lstat(entry->d_name, &statbuf);
        if(strcmp(entry->d_name ,".") == 0 || strcmp(entry->d_name , "..") == 0)
            continue;

        if(S_ISDIR(statbuf.st_mode))
        {
            cout<<"enter directory :"<<entry->d_name<<endl;
            processDirectory(entry->d_name,pWFile);
        }
        else
        {
            if(strstr(entry->d_name,"html") != NULL)
            {
                cout<<"process file : "<<entry->d_name<<endl;
                FILE * pFile=fopen(entry->d_name,"rb");
                if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
                fseek (pFile , 0 , SEEK_END);
                lSize = ftell (pFile);
                rewind (pFile);
                char * buffer = (char*) malloc (sizeof(char)*lSize);
                char * bufOut = (char*) malloc (sizeof(char)*lSize);
                if (buffer == NULL || bufOut == NULL) {fputs ("Memory error",stderr); exit (2);}
                result = fread (buffer,1,lSize,pFile);
                if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
                for(i=0,j=0;i<lSize;i++)
                {
                    if(*(buffer+i) == 10 ||*(buffer+i) == 13 )
                        continue;
                    else
                        *(bufOut+j++)=*(buffer+i);
                }
                *(bufOut+j)=13;

                fwrite(bufOut,1,j+1, pWFile);
                free(buffer);
                free(bufOut);
                fclose(pFile);
            }
        }
    }
    chdir("..");
    closedir(dp);    
}

main(int argc, char ** argv)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    long lSize;
    size_t result;

    int i,j;

    FILE * pWFile = fopen("res","wb");

    if((dp = opendir(argv[1])) == NULL)
        return -1;

    processDirectory(argv[1],pWFile);
    
}

 

写了个用来程序用来把文件夹中每个文件作为一行存放到另外一个文件中。

这其中要递归的访问一个文件夹下的所有文件。 

lstat(entry->d_name, &statbuf); 

要在上面结束后根据statbuf的情况,判断文件的类型,可是却碰到了一个文件被判断成了文件夹的情况。

经过反复的排查,原因在于我再使用lstat的时候之前没有使用chdir修改当前的文件夹,导致lstat没有找到文件,失败。statbuf中的内容没有改变,还是之前的状态。

费尽周折才找到,可见检查lstat返回值的重要性啊!!! 

这里有参考手册 

http://en.wikipedia.org/wiki/Sys/stat.h

作者: welkinwalker   发布时间: 2011-06-14