如何在 C++ 中获取目录中的文件列表? [复制]
Posted
技术标签:
【中文标题】如何在 C++ 中获取目录中的文件列表? [复制]【英文标题】:How do I get a list of files in a directory in C++? [duplicate] 【发布时间】:2010-09-23 07:42:06 【问题描述】:如何获取目录中的文件列表以便处理每个文件?
【问题讨论】:
【参考方案1】:但是boost::filesystem
可以做到这一点:http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp
【讨论】:
【参考方案2】:在结合了很多sn-ps之后,终于找到了一个可复用的Windows解决方案,就是使用Visual Studio自带的ATL库。
#include <atlstr.h>
void getFiles(CString directory)
HANDLE dir;
WIN32_FIND_DATA file_data;
CString file_name, full_file_name;
if ((dir = FindFirstFile((directory + "/*"), &file_data)) == INVALID_HANDLE_VALUE)
// Invalid directory
while (FindNextFile(dir, &file_data))
file_name = file_data.cFileName;
full_file_name = directory + file_name;
if (strcmp(file_data.cFileName, ".") != 0 && strcmp(file_data.cFileName, "..") != 0)
std::string fileName = full_file_name.GetString();
// Do stuff with fileName
要访问该方法,只需调用:
getFiles("i:\\Folder1");
【讨论】:
你能说一下这是适用于 Windows 还是 Linux 或两者兼而有之? @NadavB 它使用 atlstr.h 库,我相信它仅适用于 Windows。【参考方案3】:这是 Linux 上的 C 语言示例。也就是说,如果您使用的是 Linux,并且不介意在 ANSI C 中做这些小事。
#include <dirent.h>
DIR *dpdf;
struct dirent *epdf;
dpdf = opendir("./");
if (dpdf != NULL)
while (epdf = readdir(dpdf))
printf("Filename: %s",epdf->d_name);
// std::cout << epdf->d_name << std::endl;
closedir(dpdf);
【讨论】:
事后别忘了closedir(dpdf)
在这种情况下如何获取文件(文件类型)? epdf 是一个“dirent *”
如果你正在制作一个库,则不能使用 dirent。
dpdf
和 epdf
代表什么?
当时我正在处理 PDF。这些名字可以是你喜欢的任何名字。【参考方案4】:
C++11/Linux 版本:
#include <dirent.h>
if (auto dir = opendir("some_dir/"))
while (auto f = readdir(dir))
if (!f->d_name || f->d_name[0] == '.')
continue; // Skip everything that starts with a dot
printf("File: %s\n", f->d_name);
closedir(dir);
【讨论】:
【参考方案5】:我刚刚问了一个类似的question,这是我根据收到的答案的解决方案(使用boost::filesystem
库):
#include <string>
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;
int main()
path p("D:/AnyFolder");
for (auto i = directory_iterator(p); i != directory_iterator(); i++)
if (!is_directory(i->path())) //we eliminate directories in a list
cout << i->path().filename().string() << endl;
else
continue;
输出如下:
file1.txt
file2.dat
【讨论】:
【参考方案6】:您可以使用以下代码获取目录中的所有文件。在 Andreas Bonini 答案中进行简单修改以删除“。”的出现。和“..”
CString dirpath="d:\\mydir"
DWORD errVal = ERROR_SUCCESS;
HANDLE dir;
WIN32_FIND_DATA file_data;
CString file_name,full_file_name;
if ((dir = FindFirstFile((dirname+ "/*"), &file_data)) == INVALID_HANDLE_VALUE)
errVal=ERROR_INVALID_ACCEL_HANDLE;
return errVal;
while (FindNextFile(dir, &file_data))
file_name = file_data.cFileName;
full_file_name = dirname+ file_name;
if (strcmp(file_data.cFileName, ".") != 0 && strcmp(file_data.cFileName, "..") != 0)
m_List.AddTail(full_file_name);
【讨论】:
【参考方案7】:void getFilesList(String filePath,String extension, vector<string> & returnFileName)
WIN32_FIND_DATA fileInfo;
HANDLE hFind;
String fullPath = filePath + extension;
hFind = FindFirstFile(fullPath.c_str(), &fileInfo);
if (hFind == INVALID_HANDLE_VALUE)return;
else
return FileName.push_back(filePath+fileInfo.cFileName);
while (FindNextFile(hFind, &fileInfo) != 0)
return FileName.push_back(filePath+fileInfo.cFileName);
String optfileName ="";
String inputFolderPath ="";
String extension = "*.jpg*";
getFilesList(inputFolderPath,extension,filesPaths);
vector<string>::const_iterator it = filesPaths.begin();
while( it != filesPaths.end())
frame = imread(*it);//read file names
//doyourwork here ( frame );
sprintf(buf, "%s/Out/%d.jpg", optfileName.c_str(),it->c_str());
imwrite(buf,frame);
it++;
【讨论】:
getFilesList方法中有2个return,return FileName.push_back(filePath+fileInfo.cFileName);后面的代码无法访问【参考方案8】:这是我使用的:
/* Returns a list of files in a directory (except the ones that begin with a dot) */
void GetFilesInDirectory(std::vector<string> &out, const string &directory)
#ifdef WINDOWS
HANDLE dir;
WIN32_FIND_DATA file_data;
if ((dir = FindFirstFile((directory + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
return; /* No files found */
do
const string file_name = file_data.cFileName;
const string full_file_name = directory + "/" + file_name;
const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (file_name[0] == '.')
continue;
if (is_directory)
continue;
out.push_back(full_file_name);
while (FindNextFile(dir, &file_data));
FindClose(dir);
#else
DIR *dir;
class dirent *ent;
class stat st;
dir = opendir(directory);
while ((ent = readdir(dir)) != NULL)
const string file_name = ent->d_name;
const string full_file_name = directory + "/" + file_name;
if (file_name[0] == '.')
continue;
if (stat(full_file_name.c_str(), &st) == -1)
continue;
const bool is_directory = (st.st_mode & S_IFDIR) != 0;
if (is_directory)
continue;
out.push_back(full_file_name);
closedir(dir);
#endif
// GetFilesInDirectory
【讨论】:
Windows 代码在启用 Unicode 的情况下编译时无法正常工作。我通过显式调用附加了“A”的 ASCII 函数来解决这个问题。具体来说,使用 WIN32_FIND_DATAA、FindFirstFileA 和 FindNextFileA 一切正常。显然这是一个黑客,但我住在一个说英语的国家,所以它对我有用。 :0 感谢示例代码! 如果你正在制作一个库,则不能使用 dirent。 @tuple_cat<dirent.h>
, <sys/stat.h>
以及肯定包含std::string
的某种文件。使用std::string
,你必须把std::
放在string
类型声明的前面并使用opendir(directory.c_str())
。【参考方案9】:
HANDLE WINAPI FindFirstFile(
__in LPCTSTR lpFileName,
__out LPWIN32_FIND_DATA lpFindFileData
);
将属性设置为仅查找目录。
【讨论】:
【参考方案10】:或者你这样做然后读出test.txt:
#include <windows.h>
int main()
system("dir /b > test.txt");
“/b”表示只返回文件名,没有更多信息。
【讨论】:
这看起来非常好用且简单,但我不知道如何使用它。您能否解释一下/b
是什么以及我们将在哪里提供目录?【参考方案11】:
您必须使用操作系统调用(例如 Win32 API)或围绕它们的包装器。我倾向于使用Boost.Filesystem,因为与 Win32 API 的混乱(以及跨平台)相比,它具有更好的接口。
如果您希望使用 Win32 API,Microsoft 在 msdn 上有一个列表 of functions 和 examples。
【讨论】:
【参考方案12】:如果您在 Windows 中并使用 MSVC,则 MSDN 库有 sample code that does this.
这是来自该链接的代码:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
void ErrorHandler(LPTSTR lpszFunction);
int _tmain(int argc, TCHAR *argv[])
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
TCHAR szDir[MAX_PATH];
size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
// If the directory is not specified as a command-line argument,
// print usage.
if(argc != 2)
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return (-1);
// Check that the input path plus 2 is not longer than MAX_PATH.
StringCchLength(argv[1], MAX_PATH, &length_of_arg);
if (length_of_arg > (MAX_PATH - 2))
_tprintf(TEXT("\nDirectory path is too long.\n"));
return (-1);
_tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
StringCchCopy(szDir, MAX_PATH, argv[1]);
StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
// Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
ErrorHandler(TEXT("FindFirstFile"));
return dwError;
// List all the files in the directory with some info about them.
do
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
_tprintf(TEXT(" %s <DIR>\n"), ffd.cFileName);
else
filesize.LowPart = ffd.nFileSizeLow;
filesize.HighPart = ffd.nFileSizeHigh;
_tprintf(TEXT(" %s %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
while (FindNextFile(hFind, &ffd) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
ErrorHandler(TEXT("FindFirstFile"));
FindClose(hFind);
return dwError;
void ErrorHandler(LPTSTR lpszFunction)
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
【讨论】:
【参考方案13】:解决此问题需要特定于平台的解决方案。在 unix/linux 上查找 opendir() 或在 Windows 上查找 FindFirstFile()。或者,有许多库会为您处理特定于平台的部分。
【讨论】:
以上是关于如何在 C++ 中获取目录中的文件列表? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Win32 句柄在 C++ 中获取文件名? [复制]