Listing files

Started by
7 comments, last by guywithknife 19 years, 2 months ago
What would be the easiest way of listing the filenames of all files (either of a particular extension, or ALL files regardless of file type) in a directory and storing this list in list of some sort (std::vector or something simular), using C++? I want to be able to do this on both windows and linux, so if someone could tell me a method for both systems, that would be great. (I'll then use conditional compilation to do the rest). Thanks in advance.
Advertisement
boost::filesystem is interesting.
Thanks, I'll take a look at it, though I was kinda hoping to do it with standard windows.h and unix equivelent, rather than a new API..
Are you *really* bent on using C++ for this? :(
from os import walk, sep # routine to walk a directory tree, and the platform's separator for filenames.def files_with_extension(in_folder, ext = ""):  # For each folder entry in the walk() output, pair up the folder name with  # each file matching the criterion, creating a list. Then collect those into  # a list of lists, and flatten it.  return sum([[x[0] + sep + y for y in x[2] if y.endswith(ext)]              for x in walk(in_folder)], [])
Yes, I need/want to use C++.
Its for a plugin system for my game engine. I want it to search for .dll/.so (depending on platform) files in a "plugin" directory and either load them, or list them for optional loading later.
I really want to just have to dump a new DLL into a directory to add its functionality to my engine, while right now I have to state its name someplace too..
There is no standard api to do this in C++. You either have to use a third-party library (like boost) or OS-specific API's.

In Windows you use FindFirstFile/FindNextFile/FindClose. I don't know how you do in in Linux.
-Mike
Thanks for the reply.
I don't mind using OS specific API's as long as I can achieve the same result on all platforms.

Ok, I managed to find how to do this.
Yes, I did it with FindFirstFile (etc).
Here is my resulting code (the linux code is untested though):

#ifdef WIN32#include <windows.h>#else#include <dirent.h>#endifvoid GetFileList (std::vector<std::string>& list, std::string dir, std::string extension){#ifdef WIN32	WIN32_FIND_DATA findData;	HANDLE fileHandle;	int flag = 1;	std::string search ("*.");	if (dir == "") dir = ".";	dir += "/";	search = dir + search + extension;	// SetCurrentDirectory(dir.c_str());	fileHandle = FindFirstFile(search.c_str(), &findData);	if (fileHandle == INVALID_HANDLE_VALUE) return;	while (flag)	{		list.push_back(findData.cFileName);		flag = FindNextFile(fileHandle, &findData);	}	FindClose(fileHandle);#else	std::string search(".");	search += extension;	DIR* dir = opendir(dir.c_str());	struct dirent* entry;	std::string temp;	while ((entry = readdir(dir)) != NULL)	{		temp = entry->d_name;		if (temp.substr(, search.size()) == search)		{			list.push_back(temp);		}	}	closedir(dir);#endif}


If someone could test this on linux, Id really appreciate it as I am unable to do so myself right now and Id like to know if it works before implementing it.
Alright, got it working in SUSE Linux. Made a few changes to get it to work. This should do the trick.

#ifdef WIN32#include <windows.h>#else#include <dirent.h>#endif#include <iostream>#include <vector>#include <string>using namespace std;void GetFileList (std::vector<std::string>& list, std::string dir, std::string extension){#ifdef WIN32	WIN32_FIND_DATA findData;	HANDLE fileHandle;	int flag = 1;	std::string search ("*.");	if (dir == "") dir = ".";	dir += "/";	search = dir + search + extension;	// SetCurrentDirectory(dir.c_str());	fileHandle = FindFirstFile(search.c_str(), &findData);	if (fileHandle == INVALID_HANDLE_VALUE) return;	while (flag)	{		list.push_back(findData.cFileName);		flag = FindNextFile(fileHandle, &findData);	}	FindClose(fileHandle);#else	std::string search(".");	search += extension;	DIR* directory = opendir(dir.c_str()); // *change	struct dirent* entry;	std::string temp;	while ((entry = readdir(directory)) != NULL) // see above change	{		temp = entry->d_name;		if (temp.find(search, 0) != string::npos) // *change		{			list.push_back(temp);		}	}	closedir(directory); // change, see first change#endif}int main(int argc, char** argv){	vector<string> list;	GetFileList(list, ".", "txt");	for(int i=0; i < list.size(); i++)		cout << list << endl;	return 0;}
Thanks!

Heh, stupid mistake! I never noticed it because the unic code never ran when I tested it, DOH!

Thanks again.

This topic is closed to new replies.

Advertisement