
FileFinderByName C++ library
v3.0.3
Table of contents
Overview
FileFinderByName is a C++ library which helps to find files by name part(s). It finds data files or device files (for example serial ports in the folder /dev/serial/by-id). The library doesn’t have third-party dependencies. The library contains the FileFinderByName C++ class and a test application. It is a CMake project. The library uses the C++17 standard (std::filesystem library) and is compatible with Linux and Windows.
FileFinderByName is general-purpose software: it is not tied to any sector or application, and the developer of a program decides what the program does with it.
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 06.04.2023 | First version |
| 2.0.0 | 17.05.2023 | - Added new method to find device by several parts of name. - Documentation updated. |
| 3.0.0 | 16.04.2024 | - Change class name to FileFinderByName. - Documentation updated. |
| 3.0.1 | 17.04.2024 | - Documentation updated. |
| 3.0.2 | 06.07.2024 | - CMake updated. - Fixed path format in Windows. |
| 3.0.3 | 15.10.2026 | - Fixed: only the names of the entries are compared with the name parts (the folder path is not compared). - An empty name part or an empty list of name parts matches nothing. - Errors of the file system give empty result without exceptions. - Windows: the folder name is UTF-8 (active code page if the folder can’t be opened as UTF-8), entries with names which are not valid UTF-16 are skipped. - The folder is read until the first matching entry. - Compiler warnings and hardening options added to CMake files. - Test application checks the library automatically. - Documentation updated. |
Library files
The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt -------------------- Main CMake file of the library.
src ------------------------------- Folder with library source code.
CMakeLists.txt ---------------- CMake file of the library.
FileFinderByName.cpp ---------- C++ implementation file.
FileFinderByName.h ------------ Library main header file.
FileFinderByNameVersion.h ----- Header file with library version.
FileFinderByNameVersion.h.in -- CMake service file to generate version header.
static ---------------------------- Folder with static files (logo).
test ------------------------------ Folder of test application.
CMakeLists.txt ---------------- CMake file of test application.
main.cpp ---------------------- Source C++ file of test application.
Portability
The library uses only the C++17 standard library (std::filesystem). The library and the test application were built and run with GCC 12 and 13 and Clang 15 and 18 on Linux x86-64, with GCC 13 and Clang 18 for Linux aarch64 (tests run under emulation) and with MSVC 14.51 on Windows (x64 and x86). Names are compared byte by byte: on Linux the names are used as they are stored in the file system, on Windows the names are converted to UTF-8.
FileFinderByName class description
Class declaration
The FileFinderByName class is declared in the FileFinderByName.h file. Class declaration:
namespace rapidpixel
{
/// File finder class.
class FileFinderByName
{
public:
/// Get current library version.
static std::string getVersion();
/// Find file by name part.
std::string find(std::string namePart,
std::string folder = "/dev/serial/by-id");
/// Find file by two or more parts of name.
std::string find(std::vector<std::string> nameParts,
std::string folder = "/dev/serial/by-id");
};
}
getVersion method
The getVersion() method returns string of current version of FileFinderByName class. Method declaration:
static std::string getVersion();
Method can be used without FileFinderByName class instance:
std::cout << "FileFinderByName class version: " << rapidpixel::FileFinderByName::getVersion() << std::endl;
Console output:
FileFinderByName class version: 3.0.3
find method
The find(…) method finds an entry of a folder (file, folder, symbolic link or device) by part(s) of its name and returns the full file name. The method reads the entries of the folder (not recursive) and compares only the names of the entries with the name parts (not the folder part of the path). The comparison is case sensitive. The method accepts file name parts (e.g. “FTDI”, “usb” etc.). The method doesn’t change the object: it can be called from several threads at the same time. The method has two overloads. Method declaration:
std::string find(std::string namePart, std::string folder = "/dev/serial/by-id");
| Parameter | Value |
|---|---|
| namePart | Part of file name. An empty name part matches nothing. |
| folder | Folder to find file. On Windows the folder, the name part and the result are UTF-8 strings (a folder which can’t be opened as UTF-8 is opened in the active code page); a folder path longer than 260 characters can be given as an absolute path with backslashes and the prefix \\?\. On other systems the strings are used without conversion. |
Returns: the method returns full file name (the folder, the separator and the name of the entry; on Windows all separators are backslashes) if it was found or returns ”“ if no entry name includes namePart, if namePart is empty or if the folder can’t be read (doesn’t exist, isn’t a folder, no permission, I/O error). If several entries match, the method returns the first one in the order of the folder listing (the order depends on the file system). The method doesn’t throw exceptions.
std::string find(std::vector<std::string> nameParts, std::string folder = "/dev/serial/by-id");
| Parameter | Value |
|---|---|
| nameParts | List of name parts. To be found file must have all parts in its name (in any order). An empty list or a list with an empty name part matches nothing. A list of string literals must be given with its type, for example std::vector<std::string>{“FTDI”, “port0”}: a braced list of two string literals can be converted to std::string too, and the call is ambiguous. |
| folder | Folder to find file (the same as for the first overload). |
Returns: the method returns full file name if it was found or returns ”“ if no entry name includes all nameParts, if the list is empty or has an empty name part or if the folder can’t be read. The other properties of the result are the same as for the first overload.
Example
Example shows how to use file finder in both ways: by one part of name and by several parts of name.
#include <iostream>
#include <string>
#include <vector>
#include "FileFinderByName.h"
int main()
{
std::cout << "File finder v" << rapidpixel::FileFinderByName::getVersion()
<< std::endl;
// Set name parts and folder.
std::string namePart;
std::string secondNamePart;
std::string folder;
std::cout << "Set file name part: ";
std::cin >> namePart;
std::cout << "Set second file name part: ";
std::cin >> secondNamePart;
std::cout << "Set folder: ";
std::cin >> folder;
if (!std::cin)
{
std::cout << "Wrong input" << std::endl;
return 1;
}
// Find file by one part of name.
rapidpixel::FileFinderByName finder;
std::string file = finder.find(namePart, folder);
if (file.empty())
{
std::cout << "Can't find file" << std::endl;
}
else
{
std::cout << "File: " << file << std::endl;
}
// Find file by two parts of name (the name must have both parts).
file = finder.find(std::vector<std::string>{namePart, secondNamePart},
folder);
if (file.empty())
{
std::cout << "Can't find file" << std::endl;
}
else
{
std::cout << "File: " << file << std::endl;
}
return 0;
}