scandir(3)

#include <dirent.h>

int scandir(const char *dirp, struct dirent ***namelist,
      int (*filter)(const struct dirent *),
      int (*compar)(const struct dirent **, const struct dirent **));

 

scandir(3)은 파라미터로 넘겨진 dirp 디렉토리에 있는 파일 및 디렉토리 목록을 filter함수에서 정제하여 compar의 비교 조건으로 sorting합니다. 이 함수는 opendir(3), readdir(3), closedir(3)을 한번에 처리하고 filter와 sorting 기능을 갖는 함수입니다. 이 함수를 통하여 파일명/디렉토리명 순서나 생성 시간 순서 등으로 sorting하고 정해진 규칙(filter)의 파일/디렉토리만 목록으로 얻을 수 있습니다.

 

 

파라미터

dirp
    - 파일 목록 또는 디렉토리 목록을 얻을 디렉토리에 대한 절대 path 또는 상대 path
namelist
    - namelist에 디렉토리에 있는 파일 및 디렉토리 목록이 저장됩니다.
    - 내부적으로 malloc(3) 또는 realloc(3)으로 할당되므로 사용후에는 반드시 free(3)를 해야합니다. 
    - 다중 pointer 변수를 선언해서 사용하므로 건별 free(3) 후 namelist 자체도 free(3)를 해야합니다. (예제 참조)
filter
    - namelist에 포함시킬 것인지 여부를 판단하는 함수에 대한 pointer.
    - 이 filter함수의 return 값이 0이면 namelist에 포함시키지 않고 0이 아니면 포함시킵니다.
    - NULL이면 filter없이 파일 및 디렉토리 전체가 namelist에 저장됩니다.
    - . 및 .. 디렉토리도 포함되어 있음.
compar
    - 데이터를 sort할 비교함수에 대한 포인터입니다.
    - 내부적으로 qsort(3)를 사용하므로 이 함수를 통하여 sorting합니다. 
    - 만약 이름(struct dirent 구조체의) d_name으로 sorting하려고 한다면 이미 구현된 alphasort(3)함수를 사용할 수 있습니다.
    - 만약 이 compar를 NULL로 설정하면 sorting없이 출력됩니다.

 

RETURN

-1
    - 오류가 발생하였으며, 상세한 오류 내용은 errno에 설정됩니다.

    ENOENT : dirp 디렉토리가 존재하지 않는 path입니다.
    ENOMEM : 메모리 부족으로 처리되지 않았습니다.
    ENOTDIR : dirp가 존재는 하나 directory가 아닙니다.


0 이상
    - 정상적으로 처리 되었으며, namelist에 저장된 struct dirent *의 갯수가 return됩니다.

 


활용 예제

 

 

Sample 1. 디렉토리의 파일 및 디렉토리 목록을 오름차순으로 출력

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

const char *path = ".";

int main(void)
{
    struct  dirent **namelist;
    int     count;
    int     idx;

    if((count = scandir(path, &namelist, NULL, alphasort)) == -1) {
        fprintf(stderr, "%s Directory Scan Error: %s\n", path, strerror(errno));
        return 1;
    }

    for(idx = 0; idx < count; idx++) {
        printf("%s\n", namelist[idx]->d_name);
    }

    // 건별 데이터 메모리 해제
    for(idx = 0; idx < count; idx++) {
        free(namelist[idx]);
    }

    // namelist에 대한 메모리 해제
    free(namelist);

    return 0;
}

 

Sample 2. 디렉토리의 파일 및 디렉토리 목록을 오름차순으로 출력

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

const char *path = ".";

int main(void)
{
    struct  dirent **namelist;
    int     count;
    int     idx;

    if((count = scandir(path, &namelist, NULL, alphasort)) == -1) {
        fprintf(stderr, "%s 디렉토리 조회 오류: %s\n", path, strerror(errno));
        return 1;
    }

    for(idx = count - 1; idx >= 0; idx--) {
        printf("%s\n", namelist[idx]->d_name);
    }

    // 건별 데이터 메모리 해제
    for(idx = 0; idx < count; idx++) {
        free(namelist[idx]);
    }

    // namelist에 대한 메모리 해제
    free(namelist);

    return 0;
}

 

Sample3. 파일의 확장자가 .bak파일의 목록을 얻어서 삭제함.

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

int backup_file_only(const struct dirent *info)
{
    char *ext;

    ext = strrchr(info->d_name, '.');

    if(ext == NULL) {
        return 0;  /* 확장자가 없으면 skip함 */
    }

    if(strcmp(ext, ".bak") == 0) {
        return 1;  /* 목록에 포함 시킴 */
    } else {
        return 0;  /* 목록에 포함 시키지 않음 */
    }
}

int main(void)
{
    struct  dirent **namelist;
    int     count;
    int     idx;
    char    file_path[1024];
    const char *path = ".";

    if((count = scandir(path, &namelist, backup_file_only, alphasort)) == -1) {
        fprintf(stderr, "%s 디렉토리 조회 오류: %s\n", path, strerror(errno));
        return 1;
    }

    for(idx = 0; idx < count; idx++) {
        snprintf(file_path, 1024, "%s/%s", path, namelist[idx]->d_name);
        if(unlink(file_path) == 0) {
            printf("%s file이 삭제되었습니다.\n", namelist[idx]->d_name);
        } else {
            fprintf(stderr, "%s file이 삭제 오류: %s.\n", namelist[idx]->d_name, strerror(errno));
        }
    }

    // 건별 데이터 메모리 해제
    for(idx = 0; idx < count; idx++) {
        free(namelist[idx]);
    }

    // namelist에 대한 메모리 해제
    free(namelist);

    return 0;
}

 


see also :

    File 속성 정보 및 파일 관리 Library

    Directory 정보 조회 및 관리 Library

    System Call File I/O Library

    Stream File I/O Library

 

 

 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

댓글을 달아 주세요