반응형
    
    
    
  
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 또는 상대 pathnamelist
    - 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 :
반응형
    
    
    
  'C언어 header > dirent.h' 카테고리의 다른 글
| telldir(3) - 디렉토리 정보를 읽는 현재 위치 얻기 (0) | 2019.09.23 | 
|---|---|
| seekdir(3) - 다음 읽을 위치를 지정함 (0) | 2019.09.23 | 
| rewinddir(3) - 디렉토리 정보 읽기 위치를 처음으로 이동 (0) | 2019.09.23 | 
| readdir(3) - 디렉토리 소속의 파일정보를 읽음 (0) | 2019.09.23 | 
| opendir(3)/fdopendir(3) - 디렉토리의 파일목록 조회 시작 (0) | 2019.09.23 | 
 
							 
							