c++ 得到指定目錄下指定檔名 windows vs2010
阿新 • • 發佈:2019-02-05
c++ 得到指定目錄下指定檔名方法頗多,網上尋找總結有:
1. 主要思路是使用第三方庫 dirent.h 檔案來完成
資料結構:
struct dirent { long d_ino; /* inode number 索引節點號 */ off_t d_off; /* offset to this dirent 在目錄檔案中的偏移 */ unsigned short d_reclen; /* length of this d_name 檔名長 */ unsigned char d_type; /* the type of d_name 檔案型別 */ char d_name [NAME_MAX+1]; /* file name (null-terminated) 檔名,最長255字元 */ } struct __dirstream { void *__fd; /* `struct hurd_fd' pointer for descriptor. */ char *__data; /* Directory block. */ int __entry_data; /* Entry number `__data' corresponds to. */ char *__ptr; /* Current pointer into the block. */ int __entry_ptr; /* Entry number `__ptr' corresponds to. */ size_t __allocation; /* Space allocated for the block. */ size_t __size; /* Total valid data in the block. */ __libc_lock_define (, __lock) /* Mutex lock for this structure. */ }; typedef struct __dirstream DIR;
stackoverflow示例
DIR *dir; struct dirent *ent; if ((dir = opendir ("c:\\src\\")) != NULL) { /* print all the files and directories within directory */ while ((ent = readdir (dir)) != NULL) { printf ("%s\n", ent->d_name); } closedir (dir); } else { /* could not open directory */ perror (""); return EXIT_FAILURE; }
#include <sys/types.h> #include <dirent.h> #include <unistd.h> #include <stdio.h> int main(){ DIR *dir; struct dirent *ptr; dir = opendir("."); ///open the dir while((ptr = readdir(dir)) != NULL) ///read the list of this dir { #ifdef _WIN32 printf("d_name: %s\n", ptr->d_name); #endif #ifdef __linux printf("d_type:%d d_name: %s\n", ptr->d_type,ptr->d_name); #endif } closedir(dir); return 0; }
2. 主要思路是利用 boot filesystem module 來完成。如果是交叉平臺上,最好的方法是使用庫來完成。
給定一個路徑和檔名,以下函式迭代地在該目錄和該目錄下的子目錄中搜索該檔案,返回一個布林值,和如果成功找到的檔案的路徑。
bool find_file( const path & dir_path, // in this directory,
const std::string & file_name, // search for this name,
path & path_found ) // placing path here if found
{
if ( !exists( dir_path ) ) return false;
directory_iterator end_itr; // default construction yields past-the-end
for ( directory_iterator itr( dir_path );
itr != end_itr;
++itr )
{
if ( is_directory(itr->status()) )
{
if ( find_file( itr->path(), file_name, path_found ) ) return true;
}
else if ( itr->leaf() == file_name ) // see below
{
path_found = itr->path();
return true;
}
}
return false;
}
3. 主要思路是使用io.h提供的 handle_File =_findfirst( filespec, &fileinfo) 與 _findnext( handle_File, &fileinfo) 函式完成。
其中 handle_File 是檔案控制代碼
filespec 是指定檔案特性
fileinfo 是裝有檔案資訊的結構體
函式名稱:_findfirst函式功能:搜尋與指定的檔名稱匹配的第一個例項,若成功則返回第一個例項的控制代碼,否則返回-1L
函式原型:long _findfirst( char *filespec, struct _finddata_t *fileinfo );
標頭檔案:io.h
函式名稱:_findnext
函式功能:搜尋與_findfirst函式提供的檔名稱匹配的下一個例項,若成功則返回0,否則返回-1
函式原型:int _findnext( intptr_t handle, struct _finddata_t *fileinfo);
標頭檔案:io.h
程式舉例(http://baike.baidu.com/view/1186290.htm)
#include<io.h>
#include<stdio.h>
int main()
{
long Handle;
struct _finddata_t FileInfo;
if((Handle=_findfirst("D:\\*.txt",&FileInfo))==-1L)
printf("沒有找到匹配的專案\n");
else
{
printf("%s\n",FileInfo.name);
while(_findnext(Handle,&FileInfo)==0)
printf("%s\n",FileInfo.name);
_findclose(Handle);
}
return 0;
}
相關部落格有:
4. 一個函式就夠,不需要三方庫
函式如下:
#include <Windows.h>
vector<string> get_all_files_names_within_folder(string folder)
{
vector<string> names;
char search_path[200];
sprintf(search_path, "%s*.*", folder.c_str());
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(search_path, &fd);
if(hFind != INVALID_HANDLE_VALUE)
{
do
{
// read all (real) files in current folder
// , delete '!' read other 2 default folder . and ..
if(! (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
names.push_back(fd.cFileName);
}
}while(::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
return names;
}
以上不少方法參見此貼
實踐過方法3,並簡化為只訪問指定目錄下指定檔案(不訪問字目錄):
#ifndef GETDIRECTORY_REDUCED_H
#define GETDIRECTORY_REDUCED_H
#include <stdlib.h>
#include <direct.h>
#include <string>
#include <io.h>
class CBrowseDir
{
private:
char m_szDir[_MAX_PATH];
int m_nFileCount; //儲存檔案個數
long int handle_File;
public:
CBrowseDir();
//設定初始目錄為dir,指定檔案filespec,如果返回false,表示目錄不可用
bool SetDir(const char *dir, const char *filespec);
//遍歷目錄dir下由filespec指定的檔案,不訪問子目錄,如果返回false,表示中止遍歷檔案
bool BrowseDir(const char *filespec);
//每次呼叫給出該目錄下的下一個指定檔案的路徑,成功返回true
bool CBrowseDir::NextFile(std::string &);
//返回檔案個數
int GetFileCount();
};
#endif
#include <stdlib.h>
#include <direct.h>
#include <string>
#include <io.h>
#include <stdio.h>
#include <iostream>
#include "GetDirectory_Reduced.h"
using namespace std;
CBrowseDir::CBrowseDir()
{
//用當前目錄初始化m_szDir
_getcwd(m_szDir,_MAX_PATH);
//如果目錄的最後一個字母不是'\',則在最後加上一個'\'
int len=strlen(m_szDir);
if (m_szDir[len-1] != '\\')
{
m_szDir[len]='\\';
m_szDir[len+1]='\0';
}//strcat(m_szDir,"\\");
m_nFileCount=0;
}
bool CBrowseDir::SetDir(const char *dir, const char *filespec)
{
//先把dir轉換為絕對路徑
if (_fullpath(m_szDir,dir,_MAX_PATH) == NULL)
return false;
//判斷目錄是否存在,並轉到指定目錄m_szDir下
if (_chdir(m_szDir) != 0)
return false;
//如果目錄的最後一個字母不是'\',則在最後加上一個'\'
int len=strlen(m_szDir);
if (m_szDir[len-1] != '\\')
{
m_szDir[len]='\\';
m_szDir[len+1]='\0';
}//strcat(m_szDir,"\\");
_chdir(m_szDir);//轉換到指定目錄下
_finddata_t fileinfo;
handle_File=_findfirst(filespec,&fileinfo);//首先查詢dir中符合要求的檔案
if(handle_File==-1)
return false;
return true;
}
bool CBrowseDir::BrowseDir(const char *filespec)
{
_chdir(m_szDir);
//首先查詢dir中符合要求的檔案
long hFile;
_finddata_t fileinfo;
if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
{
do
{
//檢查如果不是子資料夾,則進行處理
if (!(fileinfo.attrib & _A_SUBDIR))
{
string filename(m_szDir);//用string來處理,避免strcpy、strcat帶來的warning
filename+=fileinfo.name;
cout << filename << endl;
m_nFileCount++;//檔案數加1
}
} while (_findnext(hFile,&fileinfo) == 0);
_findclose(hFile);
}
return true;
}
bool CBrowseDir::NextFile(string &nextfilename)
{
_finddata_t fileinfo;
while(_findnext(handle_File,&fileinfo) == 0)
{
//檢查如果不是子資料夾,則進行處理
if((fileinfo.attrib & _A_SUBDIR))
continue;
string filename(m_szDir);//用string來處理,避免strcpy、strcat帶來的warning
filename+=fileinfo.name;
cout << filename << endl;
nextfilename=filename;
m_nFileCount++;//檔案數加1
return true;
}
_findclose(handle_File);
return false;
}
//返回檔案個數
int CBrowseDir::GetFileCount()
{
return m_nFileCount;
}