카테고리 없음

wi32API / 파일검색 / MFC 파일 검색 예제 / _WIN32_FIND_DATA 구조체를 이용함

. . . 2011. 11. 24. 10:06
반응형

MFC에서는 CFile 클래스를 제공하긴 하지만 이 클래스는 디렉토리 또는 파일 검색과 같은 작업은 지원하지 않는다. 
MFC에서 이와같은 작업을 하려면 Win32 API를 사용하는 수 밖에 없다.

사용할 API 함수들은 다음과 같다.

// 검색할 파일의 핸들을 얻는다.

HANDLE FindFirstFile(
LPCTSTR lpFileName, // 찾을 파일명 문자열 포인터
LPWIN32_FIND_DATA lpFindFileData // 검색결과를 돌려줄 구조체 포인터
);

BOOL FindNextFile(
HANDLE hFindFile, // 검색할 핸들
LPWIN32_FIND_DATA lpFindFileData // 검색결과를 돌려줄 구조체 포인터
);

BOOL FindClose( 
HANDLE hFindFile // 검색에 사용된 파일의 핸들
);


FindFirstFile()의 첫번째 인자는 검색할 디렉토리나 파일명을 가진 널로 끝나는 문자열의 포인터이다. 
경로가 포함되지 않는다면 현재 디렉토리에 대해서만 검색한다. 또 와일드 카드 문자 ( *, ? )도 사용할 수 있다.
검색이 성공하면 두번째 인자인 WIN32_FIND_DATA형 구조체(포인터로 주어진)를 검색결과 정보로 채워주고 검색에 사용될 핸들을 반환하지만 실패하면  INVALID_HANDLE_VALUE 상수를 반환한다.

첫번째 검색 이후에 계속 검색을 하려면 두번째부터는 FindNextFile() 함수를 사용해야 한다. 

이 함수의 첫번째 인자는 FindFirstFile()로 얻은 검색핸들이다.  
마찬가지로 두번째 인자는 검색된 하위디렉토리나 파일의 정보를 받을 구조체의 포인터이다. 검색이 성공하면 '0'이 아닌 값, 실패하면 '0'을 반환한다.

검색이 종료되면 처음에 얻었던 검색핸들을 되돌려 주어야 하는데 이 때 사용하는 함수가 FindClose()이다.

다음은 WIN32_FIND_DATA형 구조체의 모습이다.

typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes; 
FILETIME ftCreationTime; // 파일이 만들어진 시간
FILETIME ftLastAccessTime; // 마지막으로 읽었던 시간
FILETIME ftLastWriteTime; // 마지막으로 기록했던 시간
DWORD nFileSizeHigh; // 파일의 크기
DWORD nFileSizeLow; // " "
DWORD dwReserved0; // 미래의 파일형태를 위한 예약 공간
DWORD dwReserved1; // " "
TCHAR cFileName[ MAX_PATH ]; 
TCHAR cAlternateFileName[ 14 ]; 
} WIN32_FIND_DATA;

위에서 설명하지 않은 멤버들만 소개하겠다.
    ㄴ 맨 끝에 있는 cFileName과 cAlternateFileName은 둘다 널로 끝나는 문자열로 파일명을 나타낸다. 윈도우즈처럼 긴 파일명을 지원할 경우엔 cFileName으로부터, 도스 형태의 파일명을 사용할 땐 cAlternateFileName으로부터 파일명을 얻게 된다.
    ㄴ 첫번째 멤버인 dwFileAttributes는 검색한 파일 (또는 디렉토리)의 속성을 나타내는 상수값 (DWORD)으로 다음 중 하나 또는 그 이상의 값을 가질 수 있다.

  - FILE_ATTRIBUTE_ARCHIVE ; 검색된 개체가 파일임.
  - FILE_ATTRIBUTE_COMPRESSED ; 검색된 파일이나 디렉토리가 압축됨.
  - FILE_ATTRIBUTE_DIRECTORY ; 검색된 개체가 디렉토리임.
  - FILE_ATTRIBUTE_HIDDEN ; 검색된 파일이 숨김 속성을 가지고 있음.
  - FILE_ATTRIBUTE_NORMAL ; 검색파일이 특별한 속성(숨김, 읽기전용, 시스템)을 가지지 않음. 이 값만 설정되어 있을때만 유효.
  - FILE_ATTRIBUTE_OFFLINE ; 파일의 데이터를 즉시 사용할 수 없음.
  - FILE_ATTRIBUTE_READONLY ; 검색된 파일이 읽기전용 속성을 가짐. (쓰거나 지울 수 없음)
  - FILE_ATTRIBUTE_SYSTEM ; 검색된 파일이 시스템 속성을 가짐.
  - FILE_ATTRIBUTE_TEMPORARY ; 검색된 파일이 임시로 저장된 파일임.
사용예;

HANDLE hFind;
WIN32_FIND_DATA fd;

BOOL bRet =TRUE;
int index = 0;

CStringArray straryFn;

hFind = FindFirstFile( "*.dat", &fd );

while ( hFind != INVALID_HANDLE_VALUE && bRet )
{
    if (( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 )
    {
        straryFn.Add( fd.cFileName );
    }
    bRet = FindNextFile( hFind, &fd );
}

FindClose( hFind );

위의 예에선 확장자가 "dat"인 파일을 검색하고 있다.
처음 FindFirstFile() 호출로 해당 파일이 검색됐다면 (리턴값은 INVALID_HANDLE_VALUE가 아니므로) 이후, 계속 검색하는 동안 (while 반복문)에는 FindNextFile()을 사용하여 원하는 파일이 검색되었는지 확인한다. 파일이나 디렉토리가 검색되는 동안은 while 문 내에서 계속 반복되며 그 동안 WIN32_FIND_DATA 구조체 fd의 dwFileAttributes 멤버와 FILE_ATTRIBUTE_DIRECTORY 상수값의 AND 연산 결과가 '0' 이라면 검색된 것은 파일이란 뜻이다. 따라서 이 때 스트링 배열의 크기를 늘리고 파일명을 저장한다. 
while 문이 종료되면 FindClose()를 호출하여 핸들을 돌려주고 종료한다.

CStringArray형 배열은 프로그램 실행중에 배열의 크기를 임의로 변경할 수 있는 장점이 있다. 
이 클래스에 대해서는 클래스 라이브러리를 참조하기 바란다.

예제와 다른 작업을 하고 싶다면, 예를들어 디렉토리를 검색하거나 특정 속성을 지닌 파일을 검색하는 등등의 경우에도 큰 틀은 벗어나지 않는다. 다만 dwFileAttributes 멤버의 값을 원하는 상태를 표시하는 상수값과 비교하기만 하면 된다.

반응형