Sign in to follow this  
issch

Listing files

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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)], [])

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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>
#endif

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* 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.

Share this post


Link to post
Share on other sites
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[i] << endl;

return 0;
}


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this