C, C++2007. 5. 11. 17:54

 

출처 : codeproject.com

 

파일을 찾아 주는 클래스와 예제입니다.

STL 사용하고, 콘솔 환경 외에서 실행하시면 문제가 생길 있습니다.

(현재 디버깅 중이며, 되면 공개 하겄습니다.)

그리고, 기본 공개 클래스를 임의의로 수정한 것입니다.

(원문을 원하시면 주석의 링크로 가보세요.)

 


// win32fileiterator.h 
//////////////////////////////////////////////////////////////////////////

#ifndef __WIN32_FILE_ITERATOR_H_F3019690_E6A6_4997_AB83_E0FDDC109DE2__
#define __WIN32_FILE_ITERATOR_H_F3019690_E6A6_4997_AB83_E0FDDC109DE2__

#ifndef _WIN32
#error
32-
bit Windows required.
#endif

#include
<windows.h
>

#include <iterator
>
#include <string
>

//////////////////////////////////////////////////////////////////////////
// initial class : codeproject.com

// (http://www.codeproject.com/file/win32fileiter.asp)
// updated by j2doll
//  v0.1 (10, May, 2005) : unicode / mbcs stl support 
//                       it's tested on windows xp sp2 / visual c++ 2005 sp1  
//
//////////////////////////////////////////////////////////////////////////

class win32_file_iterator : public std::iterator<std::
input_iterator_tag,
#ifdef _UNICODE
  std
::wstring
>
#else
  std
::string
>
#endif
{

private:
  class internal_handle_data{
  public:
    internal_handle_data():_h(NULL), _ref(
0
){}
    void setHandle(HANDLE handle){ _h
=
handle; }
    HANDLE getHandle(){ return _h; }
    void incRef(){ _ref
++
; }
    unsigned decRef(){ return
--
_ref; }
    operator HANDLE(){ return _h; }
  private:
    HANDLE _h;
    unsigned _ref;
  };

public:
  win32_file_iterator(
#ifdef _UNICODE
    std
::
wstring strfilter,
#else
    std
::
string strfilter,
#endif
    bool bFullPath
=
false,
    DWORD flag
= FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|
FILE_ATTRIBUTE_DIRECTORY):
    _bEnd(false), _bFullPath(bFullPath), _flag(flag){
        HANDLE h
= ::FindFirstFile(strfilter.c_str(), &
_wfd);
    _handle.setHandle(h);

    if(h
==
INVALID_HANDLE_VALUE){
      _bEnd
=
true;
    }else{
      _handle.incRef();
#ifdef _UNICODE
      std
::wstring::size_type n1 = strfilter.find_last_of(L"\\"
);
#else
      std
::string::size_type n1 = strfilter.find_last_of("\\"
);
#endif
      _strroot
= strfilter.substr(0,n1+1
);
      _chkvalid(_wfd);
    }
  }

  win32_file_iterator():_bEnd(true){}

  win32_file_iterator(win32_file_iterator
&
rhs){
   
    _handle
=
rhs._handle;
    _handle.incRef();

    _flag
=
rhs._flag;
    _bFullPath
=
rhs._bFullPath;
    _bEnd
=
rhs._bEnd;
    _wfd
=
rhs._wfd;
    _strfname
=
rhs._strfname;
    _strroot
=
rhs._strroot;   
  }

  ~win32_file_iterator(){
    if(_handle.decRef()
== 0 && _handle.getHandle() !=
NULL ){
      FindClose(_handle);
    }
  }

  reference operator
*
(){
    return _strfname;
  }

  bool operator
==(const win32_file_iterator&
rhs) const{
    return (_bEnd
==
rhs._bEnd);
  }
  bool operator
!=(const win32_file_iterator&
rhs) const{
    return (_bEnd
!=
rhs._bEnd);
  }

 
//Prefix
  win32_file_iterator& operator++
(){
    _findnext();
    return
*
this;
  }
 
//Posfix
  win32_file_iterator& operator++
(int){
    _findnext();
    return
*
this;
  }

private:
  void _findnext(){
    BOOL b
= ::FindNextFile(_handle, &
_wfd);
    if(b){
      _chkvalid(_wfd);
    }else{
      _bEnd
=
true;
    }
  }

  void _chkvalid(WIN32_FIND_DATA
&
_wfd){
    if(_wfd.dwFileAttributes
&
_flag){
      _getval(_wfd);
    }
    else{
      _findnext();
    }
  }
  void _getval(WIN32_FIND_DATA
&
wfd){
    if(_bFullPath)
      _strfname
= _strroot+
wfd.cFileName;
    else
      _strfname
=
wfd.cFileName;
  }

private:
  DWORD _flag;
  bool _bFullPath;
  bool _bEnd;
  internal_handle_data _handle;
  WIN32_FIND_DATA _wfd;
#ifdef _UNICODE
  std
::
wstring _strroot;
  std
::
wstring _strfname;
#else
  std
::
string _strroot;
  std
::
string _strfname;
#endif

};

#endif

 

 

// test function

void test1()
{


#ifdef _UNICODE

  std
::wstring pathstr = L"C:\\*.*";
 
// DWORD fileopt = FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL; 
  DWORD fileopt = FILE_ATTRIBUTE_DIRECTORY; 
// only directory 
  win32_file_iterator itBegin(pathstr, false, fileopt), itEnd;
  std
::vector<std::wstring>
vec(itBegin, itEnd);

  std
::
wstring strtemp;
  std
::vector<std::wstring>::
size_type i;
  for ( i
= 0 ; i < vec.size(); i ++
)
  {
    strtemp
=
vec.at( i );

    wprintf( L
"%s\r\n"
, strtemp.c_str() );
  }

#else

  std
::string pathstr = "C:\\*.*"
;
  
// DWORD fileopt = FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL;
  DWORD fileopt = FILE_ATTRIBUTE_DIRECTORY;
// only directory 
  win32_file_iterator itBegin(pathstr, false, fileopt), itEnd; 
  std
::vector<std::string>
vec(itBegin, itEnd);

  std
::
string strtemp;
  std
::vector<std::string>::
size_type i;
  for ( i
= 0 ; i < vec.size(); i ++
)
  {
    strtemp
=
vec.at( i );

    printf(
"[DIR]%s\r\n"
, strtemp.c_str() ); 
  }

#endif
}
 

 

 

http://j2doll.tistory.com/105
 
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

반응형

'C, C++' 카테고리의 다른 글

상수 포인터...  (0) 2007.05.17
최대한 잘라먹기(Maximal Munch)와 컴파일러(Compiler)  (2) 2007.05.16
TTOF2() 함수  (0) 2007.05.09
VC+6 아직도 쓴다면...  (0) 2007.05.08
CMainFrame IDR_MAINFRAME 확장자 연결 문자열  (0) 2007.04.26
Posted by Jay Two