디렉토리(directory) 접근 C++ Win32 함수 총정리

프로그래밍/c++ 2013. 2. 12. 14:56

파일 열기(읽기), 파일 저장(쓰기/생성), 디렉토리(폴더) 열기(읽기), 현재 경로(path) 변경 등 파일 시스템에 접근하기 위한 win32 함수 사용법들을 정리해 봤습니다. win32 버전 함수들을 알아두면 굳이 mfc 함수를 사용하지 않아도 되기 때문에 여러모로 좋습니다 (포스트 말미에 텍스트 코드를 첨부합니다).




1. 현재 경로(path) 알아내기 및 변경하기

2. 파일 읽기/열기(file read/open) 경로(path) 얻기

3. 파일 저장(write/save/create) 경로 얻기

4. 폴더 경로명 얻기 (folder open)

5. 현재 경로를 루트(root)로 폴더 선택하기 (Unicode encoding)

6. 현재 경로를 루트(root)로 폴더 선택하기 (Multi-Byte or No encoding)

7. 현재 폴더(디렉토리)의 파일 목록(리스트) 접근하기

8. 경로 분해하기

9. 현재 날짜, 시간을 파일명에 덧붙이기

10. 상위 디렉토리(폴더)로 이동하기

11. 코드 다운로드


1. 현재 경로(path) 알아내기 및 변경하기

TCHAR sPath[MAX_PATH] = {0,};

::GetCurrentDirectory(MAX_PATH, sPath);

::SetCurrentDirectory(_T("c:\\"));


2. 파일 읽기/열기(file read/open) 경로(path) 얻기

파일 열기 대화상자 사용법입니다. 아래 예제에서는 avi 파일을 열도록 필터를 설정했습니다. 필터 없이 모든 파일을 보여주려면 lpstrFilter에 NULL을 주면 됩니다.

TCHAR szFilePath[MAX_PATH] = {0,};

OPENFILENAME ofn;

ZeroMemory(&ofn, sizeof(OPENFILENAME));

ofn.lStructSize = sizeof(OPENFILENAME);

ofn.hwndOwner = NULL;

ofn.lpstrFile = szFilePath;

ofn.nMaxFile = sizeof(szFilePath);

ofn.lpstrFilter = _T("Avi Files(*.avi)\0*.avi\0All Files (*.*)\0*.*\0");

ofn.nFilterIndex = 1;

ofn.lpstrFileTitle = NULL;

ofn.nMaxFileTitle = 0;

ofn.lpstrInitialDir = NULL;

ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

if(::GetOpenFileName(&ofn)==false) return;


TCHAR *return_path = ofn.lpstrFile;


3. 파일 저장(write/save/create) 경로 얻기

파일 저장 대화상자 사용법입니다. 아래 예와 같이 필터(*.avi)를 사용한다고 해서 자동으로 avi가 확장자로 붙는건 아닙니다. 사용자가 입력한 경로명을 보고 필요한 경우 프로그래머가 직접 확장자를 추가해 주어야 합니다. 필터를 해제하려면 lpstrFilter에 NULL을 주면 됩니다.

TCHAR szFile[260] = _T("");

OPENFILENAME ofn;

ZeroMemory(&ofn, sizeof(OPENFILENAME));

ofn.lStructSize = sizeof(OPENFILENAME);

ofn.hwndOwner = NULL;

ofn.lpstrFile = szFile;

ofn.nMaxFile = sizeof(szFile);

ofn.lpstrFilter = _T("Avi Files(*.avi)\0*.avi\0All Files (*.*)\0*.*\0");

ofn.nFilterIndex = 1;

ofn.lpstrFileTitle = NULL;

ofn.nMaxFileTitle = 0;

ofn.lpstrInitialDir = NULL;

ofn.Flags = OFN_OVERWRITEPROMPT;

if(::GetSaveFileName(&ofn)==false) return;


TCHAR *return_path = ofn.lpstrFile;


4. 폴더 경로명 얻기 (folder open)

파일이 아닌 폴더(디렉토리)를 열고자 할 때는 다음과 같이 합니다.

TCHAR cpath[MAX_PATH] = _T("");

LPITEMIDLIST pDirList;

BROWSEINFO browseInfo;

browseInfo.hwndOwner = NULL;

browseInfo.pidlRoot = NULL;

browseInfo.lpszTitle = _T("이미지들을 불러올 폴더를 선택해 주세요");

browseInfo.pszDisplayName = cpath;

browseInfo.ulFlags = BIF_RETURNONLYFSDIRS;

browseInfo.lpfn = NULL;

browseInfo.lParam = 0;

pDirList = SHBrowseForFolder(&browseInfo);

if(pDirList == NULL) return;

SHGetPathFromIDList(pDirList, cpath);


TCHAR *return_path = cpath;


5. 현재 경로를 루트(root)로 폴더 선택하기 (Unicode encoding)

현재 프로그램이 실행되는 폴더/경로를 루트로 폴더 열기 대화상자를 생성합니다 (Unicode 인코딩을 사용할 경우).

// set current directory to be root directory

TCHAR sPath[MAX_PATH] = {0};

::GetCurrentDirectory(MAX_PATH, sPath);


LPITEMIDLIST pStartDir;

ULONG nCharsParsed = 0;

LPSHELLFOLDER pShellFolder = NULL;

SHGetDesktopFolder(&pShellFolder);

HRESULT hr = pShellFolder->ParseDisplayName(NULL, NULL, sPath, &nCharsParsed, &pStartDir, NULL);

pShellFolder->Release();


// Get directory from user

TCHAR cpath[MAX_PATH];

LPITEMIDLIST pDirList;

BROWSEINFO browseInfo;

browseInfo.hwndOwner = NULL; // m_hWnd

browseInfo.pidlRoot = pStartDir;

browseInfo.lpszTitle = _T("이미지들을불러올폴더를선택해주세요");

browseInfo.pszDisplayName = cpath;

browseInfo.ulFlags = BIF_RETURNONLYFSDIRS;

browseInfo.lpfn = NULL;

browseInfo.lParam = 0;

pDirList = SHBrowseForFolder(&browseInfo);

if(pDirList == NULL) return;

SHGetPathFromIDList(pDirList, cpath);


TCHAR *return_path = cpath;


6. 현재 경로를 루트(root)로 폴더 선택하기 (Multi-Byte or No encoding)

현재 프로그램이 실행되는 폴더/경로를 루트로 폴더 열기 대화상자를 생성합니다 (Multi-byte 인코딩을 사용할 경우 또는 인코딩을 설정하지 않았을 경우).

// set current directory to be root directory

TCHAR sPath[MAX_PATH] = {0};

::GetCurrentDirectory(MAX_PATH, sPath);

OLECHAR wszPath[MAX_PATH] = {0};

MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)sPath, -1, wszPath, MAX_PATH);


LPITEMIDLIST pStartDir;

ULONG nCharsParsed = 0;

LPSHELLFOLDER pShellFolder = NULL;

SHGetDesktopFolder(&pShellFolder);

HRESULT hr = pShellFolder->ParseDisplayName(NULL, NULL, wszPath, &nCharsParsed, &pStartDir, NULL);

pShellFolder->Release();


// Get directory from user

TCHAR cpath[MAX_PATH];

LPITEMIDLIST pDirList;

BROWSEINFO browseInfo;

browseInfo.hwndOwner = NULL; // m_hWnd

browseInfo.pidlRoot = pStartDir;

browseInfo.lpszTitle = _T("이미지들을불러올폴더를선택해주세요");

browseInfo.pszDisplayName = cpath;

browseInfo.ulFlags = BIF_RETURNONLYFSDIRS;

browseInfo.lpfn = NULL;

browseInfo.lParam = 0;

pDirList = SHBrowseForFolder(&browseInfo);

if(pDirList == NULL) return;

SHGetPathFromIDList(pDirList, cpath);


TCHAR *return_path = cpath;


7. 현재 폴더(디렉토리)의 파일 목록(리스트) 접근하기

아래 예는 현재 경로의 폴더에 있는 모든 txt 파일의 파일이름을 출력하는 예입니다. 모든 파일을 접근하고 싶으면 _findfirst(“*.*”,&c_file)와 같이 하면 됩니다.

      struct _finddata_t c_file;

      intptr_t hFile = _findfirst("*.txt", &c_file);

      if(hFile==-1) return;      // no files

      do

      {

            if(c_file.attrib & _A_SUBDIR)

            {

                  // directory 처리

            }

            else if(c_file.attrib & _A_HIDDEN)

            {

                  // hidden file 처리

            }

            else

            {

                  // 일반 파일 처리

                  printf("%s\n", c_file.name);

            }

      } while(_findnext(hFile, &c_file)==0);

      _findclose(hFile);


8. 경로 분해하기

파일 경로를 드라이브, 디렉토리, 파일명, 확장자로 분리하는 함수입니다.

char fdrive[5];

char fdir[200];

char fname[100];

char fext[10];

_splitpath_s(path, fdrive, 5, fdir, 200, fname, 100, fext, 10);


9. 현재 날짜, 시간을 파일명에 덧붙이기

반복적으로 파일을 저장해야 하는 경우 현재 시간을 파일명에 덧붙이면 나중에 참조할 때 편리하기도 하고 또한 기존 파일을 실수로 덮어쓰는 것을 방지할 수 있습니다.

char save_path[MAX_PATH];

SYSTEMTIME st;

GetLocalTime(&st);

sprintf_s(save_path, MAX_PATH, "filepath_%d.%d.%d_%d.%d.txt", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute);


10. 상위 디렉토리(폴더)로 이동하기

현재 경로의 parent directory로 이동하기 위한 방법입니다.

TCHAR path[MAX_PATH] = {0,};

::GetCurrentDirectory(MAX_PATH, path);


int i = _tcslen(path) - 1;

while(i>=0 && path[i]!='\\') i--;

if(i<=0) return;

path[i] = 0;

::SetCurrentDirectory((LPCTSTR)path);



11. 코드 다운로드

DirAccess.txt


by 다크 프로그래머