IT_Programming/C · C++

[C] 해당경로의 파일만 출력하기 / 하위 디렉토리도 검사

JJun ™ 2009. 7. 1. 15:00

================================================================================================

 해당 경로를 입력받아 그 파일을 출력하는 예제

================================================================================================

 

[실행화면 : Windows]

 

 

 

================================================================================================

 

[소스코드]

/****************************************************/

/*         작성자 : creazier (블로그 주인장)              */

/****************************************************/

 

#include <stdio.h>
#include <stdlib.h>
#include <io.h>

 

typedef struct _finddata_t FILE_SEARCH; // struct _finddata_t : 파일의 정보를 가지고 있는 구조체

 

void fileListPrint(char *path, FILE_SEARCH *file_search);
void ErrorHandling(char *message);

 

int main(int argc, char *argv[])
{
     FILE_SEARCH file_search;
 
     if(argc != 2)
     {
          printf("Usage : %s <Path>\n", argv[0]);
          exit(0);
     }

 

     fileListPrint(argv[1], &file_search);

 

     return 0;
}

 

void fileListPrint(char *path, FILE_SEARCH *file_search)
{
     long h_file;
 

     // 해당 경로에 파일이 없는 경우 에러 메시지 출력 + 종료
     if((h_file = _findfirst(path, file_search)) == -1L) 
          ErrorHandling("파일이 존재하지 않습니다!");

    

     printf("[%s] 출력\n", path);
 
     do
     {
          printf("%s\n", file_search->name); // 존재하는 파일 출력
     }
     while(_findnext(h_file, file_search) == 0); // 다음 파일이 존재할 때까지...
 
     printf("=====================\n", path);

 

     _findclose(h_file);
}

 

void ErrorHandling(char *message) // 에러 메시지 처리
{
     fputs(message, stderr);
     fputc('\n', stderr);
     exit(1);
}

 

================================================================================================

 

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

 

================================================================================================

 입력받은 경로에서 하위 디렉토리까지 모두 검사해서 파일들을 출력 한다.

================================================================================================

 

[실행화면 : Linux] 

 

================================================================================================

 

[소스코드]

#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
static int  indent = 0;
char cdir[256];

 

void myfunc(char *file);
void Scandir(char *wd, void (*func)(char *), int depth);

 

int main(int argc, char *argv[])
{
     Scandir(argv[1], myfunc, 0);

     return 0;
}

 

void myfunc(char *file)
{
    printf("%s/%s\n", getcwd(cdir, 256), file);
}
 
void Scandir(char *wd, void (*func)(char *), int depth)
{
    struct dirent **items;
    int nitems, i; 

    // 인자로 받은 디렉토리로 이동한다.
    if (chdir(wd) < 0)
    {
        printf("DIR : %s\n", wd);
        perror("chdir ");
        exit(1);
    }
 
    // scandir 함수를 이용해서 현재 디렉토리의
    // 모든 파일과 디렉토리의 내용을 가져온다.
    nitems = scandir(".", &items, NULL, alphasort);
 
    // 디렉토리(파일포함) 항목의 갯수만큼 루프를 돌리며 
    // 만약 해당 파일이 디렉토리 일경우
    // Scandir 함수를 재귀 호출한다.

    for (i = 0; i < nitems; i++)
    {
        // 파일 상태를 저장하기 위한 구조체
        struct stat fstat;
 
        // 현재디렉토리, 이전디렉토리 는 무시한다.
        if ( (!strcmp(items[i]->d_name, ".")) || (!strcmp(items[i]->d_name, "..")) )
        { 
            continue;
        }
 
        // 함수포인터를 호출한다. 인자로 검색한 파일이름이 넘어간다. 
        func(items[i]->d_name);
 
        // 만약 파일이 디렉토리 이라면
        // Scandir 을 재귀 호출한다.
        // 그리고 디렉토리의 depth 레벨을 1 증가 한다.

        lstat(items[i]->d_name, &fstat);
        if ((fstat.st_mode & S_IFDIR) == S_IFDIR)
        {
            // depth만큼만 하부 디렉토리검색을 한다.
            // 0일 경우 깊이에 관계없이 검색한다.

            if (indent < (depth-1) || (depth == 0))
            {
                   indent ++;
                 Scandir(items[i]->d_name, func, depth);
            }
        }
    } 


    // 디렉토리의 depth 레벨을 1 감소시키고
    // 하위 디렉토리로 이동한다.
    indent --;
    chdir("..");
}

================================================================================================

 

 

==================================================================================

출력 형태 업그레이드 : depth를 추가해서 정보를 출력하는 예제 (총 파일 크기도 출력)

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

 

[소스코드]

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

 

// 파일의 크기를 저장하기 위한 변수
long int total_size = 0;

 

// 디렉토리 들여쓰기를 위한 디렉토리 depth 레벨 저장용
int  indent = 0;

 

// 함수는 인자로 디렉토리 이름을 입력받는다.
void dir_parser(char *wd)
{
    struct dirent **items;
    int nitems, i, j;
    struct stat fstat;
    char per;

   

    // 인자로 받은 디렉토리로 이동한다.
    if (chdir(wd) < 0)
    {
        perror("chdir ");
        exit(1);
    }

   

    // scandir 함수를 이용해서 현재 디렉토리의
    // 모든 파일과 디렉토리의 내용을 가져온다.
    nitems = scandir(".", &items, NULL, alphasort);

   

    // 디렉토리(파일포함) 항목의 갯수만큼 루프를 돌리며
    // 만약 해당 파일이 디렉토리 일경우
    // dir_parser 함수를 재귀 호출한다.

    for (i = 0; i < nitems; i++)
    {
        // 파일 상태를 저장하기 위한 구조체   
        struct stat fstat;

       

        // 현재디렉토리, 이전디렉토리 는 무시한다.
        if ( (!strcmp(items[i]->d_name, ".")) || (!strcmp(items[i]->d_name, "..")) )
        {
            continue;
        }


        // 파일의 상태를 얻어와서 fstat 로 저장한다.
        lstat(items[i]->d_name, &fstat);

 

        // 디렉토리의 depth 는 "\t" 을 통해서 이루어진다.
        // 해당 뎁스의 크기만큼 "\t" 를 반복해서 출력한다.
        for (j = 0; j < indent; j++)
        {
            printf("\t");
        }


        // 파일이름(디렉토리)이름과 크기를 출력하고
        // 총계를 내기 위해서 total_size 에 더해준다.
        printf("%s\t%d\n", items[i]->d_name, fstat.st_size);
        total_size += fstat.st_size;

  

        // 만약 파일이 디렉토리 이라면
        // dir_parser 을 재귀 호출한다.
        // 그리고 디렉토리의 depth 레벨을 1 증가 한다.
        if (S_ISDIR(fstat.st_mode) && S_ISLNK(fstat.st_mode))
        {
            indent ++;
            dir_parser(items[i]->d_name);   
        }
    }


    // 디렉토리의 depth 레벨을 1 감소시키고
    // 하위 디렉토리로 이동한다.
    indent --;
    chdir("..");
}

 

int main(int argc, char **argv)
{
    memset(direntry, 0x00, 255);
    dir_parser(argv[1]);
    printf("size is %d byte\n", total_size);
}

================================================================================================