Jump to content
  • Advertisement
Sign in to follow this  
Eriond

Win32 list all files in i directory

This topic is 5414 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to list all files in a directory. When you use FindFirstFile and FindNextFile you also get all subdirectories and I only want the files. The code I have so far is.
#include <windows.h>
#include <string>
#include <iostream>
#include <vector>
using namespace std;

typedef vector< WIN32_FIND_DATA > FileList;

bool IsDirectory( const std::string& path )
{
	return GetFileAttributes( path.c_str() ) & FILE_ATTRIBUTE_DIRECTORY;
}

int main( int argc, char* argv[] )
{
	if( argc < 2 ) return -1;
	string dirSpec = argv[1];

	FileList files;

	cout << "Target directory is " << dirSpec << endl;
	dirSpec += "\\*";

	WIN32_FIND_DATA FindFileData;
	HANDLE hFind = FindFirstFile( dirSpec.c_str(), &FindFileData );

	if( hFind == INVALID_HANDLE_VALUE ) 
	{
		cout << "Invalid file handle. Error is " << GetLastError() << endl;
		return -1;
	}
	else
	{
		if( !IsDirectory( FindFileData.cFileName ) )
		{
			files.push_back( FindFileData );
		}
		while( FindNextFile( hFind, &FindFileData ) )
		{
			if( !IsDirectory( FindFileData.cFileName ) )
			{
				files.push_back( FindFileData );
			}
		}

		DWORD dwError = GetLastError();
		if( dwError == ERROR_NO_MORE_FILES )
		{
			FindClose( hFind );
		}
		else
		{
			cout << "FindNextFile error. Error is " << dwError << endl;
			return -1;
		}
	}

	for( int i = 0; i < files.size(); ++i )
	{
		cout << files.cFileName << '\n';
	}
	cout << endl;
	return 0;
}
The problem is that IsDirectory returns true for everything FindFirstFile/FindNextFile finds. If I call the function with just the path it works as it should.

Share this post


Link to post
Share on other sites
Advertisement

bool IsDirectory(const WIN32_FIND_DATA &findData)
{
return (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}

Share this post


Link to post
Share on other sites
Thanks Oluseyi, why didn't my code work? Because if I called it like IsDirectory( "c:\\program" ) it would return true, and IsDirectory( "c:\\log.txt" ) returned false.
Do I need FindClose somewhere else the where I have it now? Most of the code is from MSDN. I have just removed some printf's and changed the char[] to a string.

Share this post


Link to post
Share on other sites
Sorry, my bad. I looked to shortly and didn't see the FindClose is already there.

Your code did work too, but since you're using FindFirstFile this will give you the file attributes already, so there's no need to retrieve them a second time.

Share this post


Link to post
Share on other sites
Quote:
Original post by Eriond
Thanks Oluseyi, why didn't my code work?
An error could have occured on GetFileAttributes(), which can only be detected by calling GetLastError(). Your IsDirectory() should have looked like this:

bool IsDirectory(const std::string & file)
{
DWORD attr = GetFileAttributes(file.c_str());
if(GetLastError() != 0) return false;
return attr & FILE_ATTRIBUTE_DIRECTORY;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!