如何在 C++ 中获取目录中的文件列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/306533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get a list of files in a directory in C++?
提问by DShook
How do you get a list of files within a directory so each can be processed?
如何获取目录中的文件列表以便处理每个文件?
采纳答案by Johannes Schaub - litb
But boost::filesystem
can do that: http://www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp
但boost::filesystem
可以这样做:http: //www.boost.org/doc/libs/1_37_0/libs/filesystem/example/simple_ls.cpp
回答by Thomas Bonini
Here's what I use:
这是我使用的:
/* 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
回答by Chris Kloberdanz
Here's an example in C on Linux. That's if, you're on Linux and don't mind doing this small bit in ANSI C.
这是 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);
回答by AdrianEddy
C++11/Linux version:
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);
}
回答by Yacoby
You have to use operating system calls (e.g. the Win32 API) or a wrapper around them. I tend to use Boost.Filesystemas it is superior interface compared to the mess that is the Win32 API (as well as being cross platform).
您必须使用操作系统调用(例如 Win32 API)或围绕它们的包装器。我倾向于使用Boost.Filesystem,因为与 Win32 API 的混乱(以及跨平台)相比,它是更好的界面。
If you are looking to use the Win32 API, Microsoft has a list of functionsand exampleson msdn.
回答by Bad
I've just asked a similar questionand here's my solution based on answer received (using boost::filesystem
library):
我刚刚问了一个类似的问题,这是我基于收到的答案(使用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;
}
}
Output is like:
输出是这样的:
file1.txt
file2.dat
回答by John Dibling
If you're in Windows & using MSVC, the MSDN library has sample code that does this.
如果您使用的是 Windows 并使用 MSVC,则 MSDN 库具有执行此操作的示例代码。
And here's the code from that link:
这是该链接中的代码:
#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);
}
回答by Roland Rabien
Solving this will require a platform specific solution. Look for opendir() on unix/linux or FindFirstFile() on Windows. Or, there are many libraries that will handle the platform specific part for you.
解决这个问题需要一个特定于平台的解决方案。在 unix/linux 上查找 opendir() 或在 Windows 上查找 FindFirstFile()。或者,有许多库可以为您处理特定于平台的部分。
回答by Jean Knapp
After combining a lot of snippets, I finally found a reuseable solution for Windows, that uses ATL Library, which comes with Visual Studio.
在结合了很多片段之后,我终于找到了一个可重用的 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
}
}
}
To access the method, just call:
要访问该方法,只需调用:
getFiles("i:\Folder1");
回答by tjdoubts
You can use the following code for getting all files in a directory.A simple modification in the Andreas Bonini answer to remove the occurance of "." and ".."
您可以使用以下代码获取目录中的所有文件。 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);
}
}