반응형
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 :
반응형
'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 |