Welcome to Exercise 2! In this project, you'll build a File Search Utility for Windows using C++. This console application allows users to search for files in a specified directory based on various criteria. It's a great opportunity to practice working with the Windows API, handling command-line arguments, and applying C++ best practices like proper string handling and resource management.
The goal is to create a single-file C++ program that is simple, efficient, and robust. You'll implement functionality to filter files by name patterns, size ranges, modification dates, and file attributes, all while keeping the code idiomatic and maintainable.
Your task is to create a command-line utility that:
- Searches files in a given directory (non-recursively).
- Filters files based on:
- File name patterns (supporting wildcards like
*
and?
). - File size ranges (minimum and maximum sizes in bytes).
- Modification date ranges (start and end dates).
- File attributes (e.g., hidden, readonly).
- File name patterns (supporting wildcards like
- Outputs the full paths of matching files to the console.
- Handles Unicode file paths for broader compatibility.
- Uses a single
.cpp
file with no external dependencies beyond standard C++ and Windows libraries.
- A Windows environment (e.g., Windows 10 or 11).
- A C++ compiler, such as:
- Visual Studio (Community Edition is fine) with C++ support.
- MinGW-w64 (ensure it includes the Windows API headers).
- Basic knowledge of:
- C++ (strings, maps, command-line argument handling).
- Windows API for file operations (e.g.,
FindFirstFile
). - Working with
FILETIME
andSYSTEMTIME
for dates.
- Create a new C++ project or a single
.cpp
file (e.g.,FileSearch.cpp
). - Ensure you link against
kernel32.lib
(included by default in most Windows C++ environments). - Write your code to handle command-line arguments and interact with the Windows file system.
Your program should accept exactly 7 command-line arguments in this order:
- Directory path (e.g.,
C:\Temp
). - File name pattern (e.g.,
*.txt
or empty for all files). - Minimum file size in bytes (e.g.,
1024
or-1
for no minimum). - Maximum file size in bytes (e.g.,
1048576
or-1
for no maximum). - Start date for modification time (e.g.,
2023-01-01
or empty for no start limit). - End date for modification time (e.g.,
2023-12-31
or empty for no end limit). - Comma-separated file attributes (e.g.,
hidden,system
or empty for no filter).
Example Command:
FileSearch.exe C:\Temp *.txt 1024 -1 2023-01-01 2023-12-31 hidden,system
Expected Output:
- Full paths of matching files, one per line, printed to the console (e.g.,
C:\Temp\example.txt
). - If no files match or the directory is invalid, handle gracefully (e.g., no output or an error message).
- Use Windows API: Leverage functions like
FindFirstFileW
andFindNextFileW
for file enumeration. Use wide-character versions (W
suffix) for Unicode support. - Handle Dates: Convert date strings to
FILETIME
for comparison with file modification times. Consider edge cases like empty date inputs. - File Attributes: Use
DWORD
flags (e.g.,FILE_ATTRIBUTE_HIDDEN
) and bitwise operations to check multiple attributes. - Error Handling: Check for invalid directories, handles, and input formats. Provide clear usage instructions if arguments are incorrect.
- Keep It Simple: Focus on non-recursive search to avoid complexity. Use standard library containers like
std::map
orstd::vector
for clean code. - Unicode Support: Use
std::wstring
and wide-character APIs to handle international file names. - Best Practices: Avoid raw pointers, use RAII for resource cleanup (e.g., closing file handles), and handle exceptions where appropriate.
By completing this exercise, you'll:
- Gain experience with Windows file system APIs.
- Practice parsing and validating command-line arguments.
- Learn to handle file attributes and timestamps in C++.
- Apply modern C++ techniques (e.g., standard library containers, type safety).
- Understand basic error handling and user feedback in console applications.
- Test with different directories, including ones with spaces or Unicode characters.
- Try various patterns (e.g.,
*.txt
,file?.doc
). - Test size ranges (e.g., files between 1 KB and 1 MB).
- Use date ranges to filter files modified within a specific period.
- Test attribute combinations (e.g., hidden and readonly files).
- Verify behavior with invalid inputs (e.g., non-existent directories, malformed dates).
- Windows API Documentation: Look up
FindFirstFileW
,FILETIME
, andSystemTimeToFileTime
on MSDN. - C++ Reference: Use
cppreference.com
forstd::wstring
,std::stringstream
, and other standard library features. - Compiler Setup: If using Visual Studio, create a "Console Application" project. For MinGW, compile with
g++ FileSearch.cpp -o FileSearch.exe
.
Get started and have fun building your file search utility! Focus on clean, maintainable code, and test thoroughly to ensure robustness.