Linux C 文件夹遍历接口.

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


#define ulogdbg printf
#define ulogerr printf




/* 递归/非递归方式遍历文件夹.
  需自行实现回调函数. */
int direntcb(const char* dir, 
        int recursive, /*是否递归。*/
        int depth, /*填0*/
        int (*cb)(const char* dir, struct dirent* d, int depth, void* arg), 
        void* arg)
{
    int ret = 0;


    ulogdbg("wavcam_direntcb at %s\n", dir);
    DIR* dirp;
    struct dirent entry;
    struct dirent* result = NULL;
    int retdir;


    dirp = opendir(dir);
    if(NULL != dirp) {
        while(1) {
            result = NULL;
            retdir = readdir_r(dirp, &entry, &result);
            if(0 != retdir) {
                ulogerr("%s error : readdir_r at %s.\n", __FUNCTION__, dir);
                ret = -1;
                break;
            }


            if(0 == retdir && NULL == result) {
                ulogdbg("%s finished at %s.\n", __FUNCTION__, dir);
                break;
            }


            if(0 == strcmp(entry.d_name, ".") 
                    || 0 == strcmp(entry.d_name, "..")) {
                continue;
            }


            retdir = cb(dir, &entry, depth, arg);
            if(0 == retdir && recursive) {
                #define LEN_DIR_PATH   (1*1024) /* 考虑到栈递归. 不宜设置过大. */
                char path[LEN_DIR_PATH];
                if(4 == entry.d_type) {
                    snprintf(path, LEN_DIR_PATH, "%s/%s", dir, entry.d_name);
                    direntcb(path, 1, depth+1, cb, arg);
                }
            }
        }


        closedir(dirp);
        dirp = NULL;
    }
    else {
        ulogerr("%s error : opendir at %s.\n", __FUNCTION__, dir);
        ret = -1;
    }


    return ret;
}
































































struct filename_list {
    char* filenames[100];
    int num;
};




int strcmptail(const char* s1, const char* s2)
{
    if(NULL != s1 && NULL != s2) {
        size_t len1 = strlen(s1);
        size_t len2 = strlen(s2);
        if(len1>=len2) {
            return strcmp(s1+(len1-len2), s2);
        }
        else {
            return -1;
        }
    }
    else {
        return -1;
    }
}




int is_video_file(const char* name)
{
    if(strcmptail(name, ".avi") 
            || strcmptail(name, ".mp4")) {
        return 1;
    }
    else {
        return 0;
    }
}




int store_video_file(const char* dir, struct dirent* d, int depth, void* arg)
{
    struct filename_list *s = arg;
    if(8 == d->d_type 
            && is_video_file(d->d_name)) {


        char name[1024];
        snprintf(name, 1024, "%s/%s", dir, d->d_name);
        if(s->num < 100) {
            s->filenames[s->num++] = strdup(name);
        }
    }


    return 0;
}


















int main()
{
    struct filename_list s;
    s.num = 0;


    direntcb("/tmp/sd", 1, 0, store_video_file, &s);


    int i;
    for(i=0; i<s.num; i++) {
        printf("%2d : %s\n", i, s.filenames[i]);
        free(s.filenames[i]);
        s.filenames[i] = NULL;
    }


    return 0;
}

你可能感兴趣的:(Linux C 文件夹遍历接口.)