본문으로 바로가기

[C] 디렉토리 검색 함수 scandir

category 프로그래밍/C 2023. 6. 29. 13:53
728x90
반응형

오늘은 C언어로 특정 경로의 디렉토리와 파일을 찾는 함수에 대해 알아보겠습니다.

scandir 함수입니다

원형은 아래와 같습니다.
-------------------------------------------------------------------------------------------------------------------------
int scandir(const char *dirpath, struct dirent ***namelist,
             int (*filter)(const struct dirent *),
             int (*compar)(const struct dirent **, const struct dirent **));
-------------------------------------------------------------------------------------------------------------------------


dirpath : 탐색할 디렉토리의 경로입니다. ex) "/var/log"
namelist : 디렉토리를 스캔한 후, 그안에 있는 파일과 디렉토리의 정보를 저장하기 위한 배열입니다. 동적으로 할당되며, 사용한 후에는 반드시 해제를 해야됩니다.
filter : filter는 함수를 등록하여 필요한 파일 혹은 디렉토리만 검색되도록 설정할 수 있습니다. NULL을 설정하면 모든 디렉토리와 파일을 보여줍니다.
compar : 디렉토리 항목을 정렬하기위해 함수를 등록할 수 있습니다.

실패하면 -1을 리턴하고, 성공하면 검색된 디렉토리와 파일 갯수를 리턴합니다.

예제는 아래와 같습니다.

아래 코드는 /root 경로에서 한 단계 하위에 있는 디렉토리와 파일 리스트를 보여줍니다.

-------------------------------------------------------------------------------------------------------------------------

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

#define PATH    "/root"

int main() {
        struct dirent **namelist=NULL;
        int count=0, idx=0;
        char path[1024]={};
        struct stat fileStat;

        count=scandir(PATH, &namelist, NULL, alphasort);

        if (count < 0) {
                printf("fail to scandir() path:%s\n", PATH);
                return;
        }

        for (idx = 0; idx < count; idx++) {
                memset(path,0x00,sizeof(path));
                snprintf(path, sizeof(path), "%s/%s", PATH, namelist[idx]->d_name);

                if (stat(path, &fileStat) < 0) {
                        printf("fail to stat() path:%s\n", path);
                        continue;
                }

                // check dir
                if (S_ISDIR(fileStat.st_mode)) {
                        if (strcmp(namelist[idx]->d_name, ".") == 0 || strcmp(namelist[idx]->d_name, "..") == 0)
                                continue;
                }

                if (S_ISREG(fileStat.st_mode)) {
                        printf("[file]%s\n",path);
                }

                free(namelist[idx]);
        }

        free(namelist);

        return 0;
}

-------------------------------------------------------------------------------------------------------------------------

실행하면 아래와 같은 결과가 나옵니다.


-------------------------------------------------------------------------------------------------------------------------
[root@test01 tmp]# ./test
[file]/root/.bash_history
[file]/root/.bash_logout
[file]/root/.bash_profile
[file]/root/.bashrc
[file]/root/.cshrc
[file]/root/.tcshrc
[file]/root/.viminfo
[file]/root/anaconda-ks.cfg
[file]/root/install.log
[file]/root/install.log.syslog
-------------------------------------------------------------------------------------------------------------------------


오늘 포스팅은 여기까지입니다.

감사합니다.

728x90
반응형