갓토리

C언어] DIR 함수, 와일드카드 지원, 디렉터리 파일 검색 본문

IT/프로그래밍

C언어] DIR 함수, 와일드카드 지원, 디렉터리 파일 검색

ZungTa 2015. 4. 4. 19:23


도스의 dir 명령에서처럼, 지정해준 디렉토리 속의 모든 파일들의 리스트를 얻기 위해서는, 비주얼C의 경우 io.h 헤더파일의

_findfirst() _findnext() 함수를 사용합니다. "*.*" 같은 와일드카드도 지원합니다.

_findfirst() 로 우선 첫번째 파일 하나를 찾은 후, 그 다음 파일부터는 _findnext() 로 계속 찾는 것입니다. 그리고 함수의 사용이 끝났으면 _findclose() 함수로, 반드시 메모리를 해제해 주어야 합니다.


그런데 _findfirst() / _findnext() 로는, 3GB가 넘는 거대한 파일을 다룰 수 없기에
현실적으로는 _findfirsti64() / _findnexti64() 함수를 사용해야 합니다.


VC++: 현재 디렉토리의, "모든 파일(*.*)" 목록 출력 예제


파일명: 0.cpp
#include <stdio.h>
#include <stdlib.h> // exit()
#include <io.h>
#include <errno.h>


int main(void) {
  _finddatai64_t c_file;
  intptr_t hFile;
  char path[] = "*.*";


  if ( (hFile = _findfirsti64(path, &c_file)) == -1L ) {
    switch (errno) {
      case ENOENT:
        printf(":: 파일이 없음 ::\n"); break;
      case EINVAL:
        fprintf(stderr, "Invalid path name.\n"); exit(1); break;
      case ENOMEM:
        fprintf(stderr, "Not enough memory or file name too long.\n"); exit(1); break;
      default:
        fprintf(stderr, "Unknown error.\n"); exit(1); break;
    }
  } // end if
  else {
    printf("-- 파일 목록 --\n");
    do {
      printf("%s\n", c_file.name);
    } while(_findnexti64(hFile, &c_file) == 0);
    _findclose(hFile); // _findfirsti64(), _findnexti64()에 사용된 메모리를 반환
  } // end else


  return 0;
}



컴파일 및 실행 결과:
D:\Z>cl /nologo 0.cpp && 0.exe
0.cpp
-- 파일 목록 --
.
..
0.bat
0.cpp
0.exe
0.obj
15698793.htm
15698793_files
antivirus_v3_plus_neo_dos_freeware.png
d0.cpp
Foo.class
Foo.java
ggg.doc
ggg.txt
Jaso.class
Jaso.java
out.txt
test.txt
강병철과 삼태기 - 냉면.mp3
새 폴더

D:\Z>



char path[] = "*.*";
이렇게 하면 "현재 디렉토리"의 모든 파일이 출력됩니다.



char path[] = "D:/Y/*.*";
이렇게 하면 "D:\Y" 폴더의 모든 파일을 출력합니다. 모든 파일 출력시, 폴더에 파일이 하나도 없더라도

.
..

이렇게 "현재 디렉토리"를 나타내는 점 1개(.)와, 상위 디렉토리를 나타내는 점 2개(..)는 나옵니다.



char path[] = "D:/Y";
이렇게 지정하면
Y
이렇게 Y 라는 디렉토리 자체가 나옵니다.




에러가 날 경우
"Invalid path name (잘못된 파일/디렉토리명)"
"Not enough memory or file name too long (메모리 부족/너무 긴 패스명)"
"Unknown error (그밖의 알 수 없는 에러)"

등의 메시지가 출력됩니다.

ENOENT 등의 에러는 컴파일러 버전에 따라서 좀 다를 수 있습니다. 이 예제는 Visual C++ 2003 에서 만들어진 것입니다.

 

C언어 VC] 도스 DIR 명령 구현; 파일 목록(리스트) 출력; 와일드 카드(Wild Card) 지원

 

도스(DOS)의 dir 명령처럼, 파일 목록을 구하는 소스입니다. 진짜 dir 명령 같은 복잡한 기능은 전혀 없고, 최소한의 기초적인 것만 있습니다.

파일 이름과 날짜와 속성만 나옵니다.

DIR (ls) 명령, FILE LIST 출력 예제; DIR Command Example Source Code


소스 파일명: 0.cpp

#include <stdio.h>
#include <stdlib.h> // exit()
#include <io.h>
#include <errno.h>
#include <time.h>

char* attribToString(unsigned attrib);
char* timeToString(struct tm *t);


int main(void) {
  _finddatai64_t c_file;
  intptr_t hFile;
  struct tm *t;
  char path[] = "*.*";


  if ( (hFile = _findfirsti64(path, &c_file)) == -1L ) {
    switch (errno) {
      case ENOENT:
        printf(":: 파일이 없음 ::\n"); break;
      case EINVAL:
        fprintf(stderr, "Invalid path name.\n"); exit(1); break;
      case ENOMEM:
        fprintf(stderr, "Not enough memory or file name too long.\n"); exit(1); break;
      default:
        fprintf(stderr, "Unknown error.\n"); exit(1); break;
    }
  } // end if
  else {
    printf("-- 파일 목록 --\n");
    do {
      t = localtime(&c_file.time_write);

      printf("%8I64d  %s %s %s\n",
        c_file.size,
        timeToString(t),
        attribToString(c_file.attrib),
        c_file.name);

    } while (_findnexti64(hFile, &c_file) == 0);
  } // end else
  _findclose(hFile);


  return 0;
}




char* attribToString(unsigned attrib) {
  static char s[4 + 1];

  (attrib & _A_ARCH  ) ? s[0] = 'A' : s[0] = ' ';
  (attrib & _A_RDONLY) ? s[1] = 'R' : s[1] = ' ';
  (attrib & _A_HIDDEN) ? s[2] = 'H' : s[2] = ' ';
  (attrib & _A_SYSTEM) ? s[3] = 'S' : s[3] = ' ';

  return s;
}


char* timeToString(struct tm *t) {
  static char s[20];

  sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d",
              t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
              t->tm_hour, t->tm_min, t->tm_sec
          );

  return s;
}



디렉토리(폴더)는 별도로 처리해 주어야 하는데, 디렉토리 처리 부분은 현재 없습니다. 디렉토리도 그냥 일반 파일처럼 보여줍니다.

"*.*" 라는 와일드 카드는 "모든 파일"이라는 뜻입니다.

파일 날짜의 연도는 4자리로, 시간은 초 단위까지 자세히 나옵니다.





출처 : http://blog.naver.com/parksangsuk/120092768248

Comments