micfox
8/21/2017 - 10:24 AM

get filenames on windows

get filenames on windows

#pragma once
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <mutex>

class Filename_getter {
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	std::string path;
	bool finder_closed;
	std::mutex get_new_filename;

public:
	Filename_getter(std::string path = "", std::string filter = "*") 
		:finder_closed{ true }
	{
		if (path.size() > MAX_PATH - 3)
		{
			std::cout << "Directory path is too long." << std::endl;
		}
		else
		{
			while (path.back() == '/' || path.back() == '\\')
				path.pop_back();

			this->path = path;

			string search_name;
			if (path == "")
				search_name = filter;
			else
				search_name = path + '/' + filter;

			hFind = FindFirstFile(search_name.c_str(), &FindFileData);

			if (hFind != INVALID_HANDLE_VALUE)
				finder_closed = false;
		}
	}

	~Filename_getter() {
		if (!finder_closed) FindClose(hFind);
	}

	// {full_name, name_only}
  std::pair<std::string, std::string> filename() {
		do {
			if (finder_closed)
				return{ "", "" };

			std::unique_lock<std::mutex> lck{ get_new_filename };

			if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
			{
				FindNextFile(hFind, &FindFileData);
				if (GetLastError() == ERROR_NO_MORE_FILES)
				{
					FindClose(hFind);
					finder_closed = true;
					return{ "", "" };
				}
				continue;
			}

			string s = FindFileData.cFileName;

			FindNextFile(hFind, &FindFileData);
			if (GetLastError() == ERROR_NO_MORE_FILES)
			{
				FindClose(hFind);
				finder_closed = true;
			}

			if (path == "")
				return{ s, s };
			else
				return{ path + "/" + s, s };
		} while (true);
	}
};