Pet*_*ker 758
在小而简单的任务中我不使用boost,我使用dirent.h,它也适用于windows:
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;
}
Run Code Online (Sandbox Code Playgroud)
它只是一个小的头文件,可以完成你需要的大部分简单的东西,而不需要使用像boost这样的基于模板的大方法(没有冒犯,我喜欢boost!).
Windows兼容层的作者是Toni Ronkko.在Unix中,它是标准头.
2017年更新:
在C++ 17中,现在有一种列出文件系统文件的官方方法:std::filesystem.下面的Shreevardhan有一个很好的答案,源代码如下:
#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
std::string path = "/path/to/directory";
for (const auto & entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
Shr*_*han 297
C++ 17现在有一个std::filesystem::directory_iterator,可以用作
#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
std::string path = "/path/to/directory";
for (const auto & entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
此外,std::filesystem::recursive_directory_iterator还可以迭代子目录.
Bri*_*ndy 228
不幸的是,C++标准没有以这种方式定义使用文件和文件夹的标准方法.
由于没有跨平台方式,最好的跨平台方式是使用诸如boost文件系统模块之类的库.
跨平台提升方法:
给定目录路径和文件名的以下函数以递归方式在目录及其子目录中搜索文件名,返回bool,如果成功,则返回找到的文件的路径.
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;
}
Run Code Online (Sandbox Code Playgroud)
来自上面提到的提升页面的来源.
对于基于Unix/Linux的系统:
你可以使用opendir/readdir/closedir.
在目录中搜索条目"name"的示例代码是:
len = strlen(name);
dirp = opendir(".");
while ((dp = readdir(dirp)) != NULL)
if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
(void)closedir(dirp);
return FOUND;
}
(void)closedir(dirp);
return NOT_FOUND;
Run Code Online (Sandbox Code Playgroud)
上述手册页的源代码.
对于基于Windows的系统:
您可以使用Win32 API FindFirstFile/FindNextFile/FindClose函数.
以下C++示例显示了FindFirstFile的最小使用.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
void _tmain(int argc, TCHAR *argv[])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
if( argc != 2 )
{
_tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
return;
}
_tprintf (TEXT("Target file is %s\n"), argv[1]);
hFind = FindFirstFile(argv[1], &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("FindFirstFile failed (%d)\n", GetLastError());
return;
}
else
{
_tprintf (TEXT("The first file found is %s\n"),
FindFileData.cFileName);
FindClose(hFind);
}
}
Run Code Online (Sandbox Code Playgroud)
来自上述msdn页面的源代码.
her*_*tao 84
一个功能就足够了,您不需要使用任何第三方库(适用于Windows).
#include <Windows.h>
vector<string> get_all_files_names_within_folder(string folder)
{
vector<string> names;
string search_path = folder + "/*.*";
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(search_path.c_str(), &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;
}
Run Code Online (Sandbox Code Playgroud)
PS:如@Sebastian所述,您可以更改*.*为*.ext仅获取该目录中的EXT文件(即特定类型).
con*_*gus 50
对于仅限C的解决方案,请查看此信息.它只需要一个额外的标题:
https://github.com/cxong/tinydir
tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");
while (dir.has_next)
{
tinydir_file file;
tinydir_readfile(&dir, &file);
printf("%s", file.name);
if (file.is_dir)
{
printf("/");
}
printf("\n");
tinydir_next(&dir);
}
tinydir_close(&dir);
Run Code Online (Sandbox Code Playgroud)
与其他选项相比有一些优势
readdir_r可用的地方,这意味着它(通常)线程安全UNICODE宏支持Windows UTF-16Chr*_*ord 29
我建议使用glob这个可重复使用的包装器.它生成一个vector<string>适合glob模式的文件路径:
#include <glob.h>
#include <vector>
using std::vector;
vector<string> globVector(const string& pattern){
glob_t glob_result;
glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result);
vector<string> files;
for(unsigned int i=0;i<glob_result.gl_pathc;++i){
files.push_back(string(glob_result.gl_pathv[i]));
}
globfree(&glob_result);
return files;
}
Run Code Online (Sandbox Code Playgroud)
然后可以使用正常的系统通配符模式调用,例如:
vector<string> files = globVector("./*");
Run Code Online (Sandbox Code Playgroud)
Bad*_*Bad 23
这是一个非常简单的代码,C++11使用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
{
cout << i->path().filename().string() << endl;
}
else
continue;
}
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
file1.txt
file2.dat
Run Code Online (Sandbox Code Playgroud)
Mee*_*ohi 22
为什么不用glob()?
#include <glob.h>
glob_t glob_result;
glob("/your_directory/*",GLOB_TILDE,NULL,&glob_result);
for(unsigned int i=0; i<glob_result.gl_pathc; ++i){
cout << glob_result.gl_pathv[i] << endl;
}
Run Code Online (Sandbox Code Playgroud)
Shr*_*ant 19
我想,下面的代码片段可用于列出所有文件.
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
static void list_dir(const char *path)
{
struct dirent *entry;
DIR *dir = opendir(path);
if (dir == NULL) {
return;
}
while ((entry = readdir(dir)) != NULL) {
printf("%s\n",entry->d_name);
}
closedir(dir);
}
Run Code Online (Sandbox Code Playgroud)
以下是struct dirent的结构
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file */
char d_name[256]; /* filename */
};
Run Code Online (Sandbox Code Playgroud)
Tim*_*Tim 10
尝试使用x-platform方法进行提升
http://www.boost.org/doc/libs/1_38_0/libs/filesystem/doc/index.htm
或者只是使用您的操作系统特定文件.
小智 8
看看这个使用win32 api的类.只需通过提供foldername您想要列表的实例来构造实例,然后调用该getNextFile方法filename从目录中获取下一个实例.我认为它需要windows.h和stdio.h.
class FileGetter{
WIN32_FIND_DATAA found;
HANDLE hfind;
char folderstar[255];
int chk;
public:
FileGetter(char* folder){
sprintf(folderstar,"%s\\*.*",folder);
hfind = FindFirstFileA(folderstar,&found);
//skip .
FindNextFileA(hfind,&found);
}
int getNextFile(char* fname){
//skips .. when called for the first time
chk=FindNextFileA(hfind,&found);
if (chk)
strcpy(fname, found.cFileName);
return chk;
}
};
Run Code Online (Sandbox Code Playgroud)
GNU手册FTW
此外,有时候直接去源(双关语)是好的.通过查看Linux中一些最常见命令的内部结构,您可以学到很多东西.我在github上设置了一个GNU coreutils的简单镜像(用于阅读).
https://github.com/homer6/gnu_coreutils/blob/master/src/ls.c
也许这不涉及Windows,但是使用这些方法可以使用许多使用Unix变体的情况.
希望有帮助......
小智 6
Shreevardhan 的回答效果很好。但是如果你想在 c++14 中使用它,只需进行更改namespace fs = experimental::filesystem;
IE,
#include <string>
#include <iostream>
#include <filesystem>
using namespace std;
namespace fs = experimental::filesystem;
int main()
{
string path = "C:\\splits\\";
for (auto & p : fs::directory_iterator(path))
cout << p << endl;
int n;
cin >> n;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
#include <string>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
std::string path = "/path/to/directory";
for (const auto & entry : fs::directory_iterator(path))
std::cout << entry.path() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
822881 次 |
| 最近记录: |