File System Operations (Win32 API)
This section details the Win32 API functions used for interacting with the file system, including creating, reading, writing, deleting, and querying files and directories.
Core Concepts
The Win32 API provides a robust set of functions for file system management. These functions operate on file handles and paths, allowing applications to perform standard file operations. Key concepts include:
- File Handles: Unique identifiers returned by functions like
CreateFile, used to refer to opened files. - File Paths: Strings representing the location of files and directories.
- I/O Operations: Reading from and writing to files.
- Directory Management: Creating, enumerating, and deleting directories.
- File Attributes: Properties of files such as read-only, hidden, system, etc.
Key Functions
Creating and Opening Files
CreateFile
HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
This is the primary function for opening or creating files. It returns a handle to the file. Parameters control access rights, sharing modes, security, and how to handle existing files.
Reading and Writing Files
ReadFile
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
Reads data from a file specified by a handle into a buffer. It can be used for both synchronous and asynchronous I/O.
WriteFile
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
Writes data from a buffer to a file specified by a handle. Similar to ReadFile, it supports synchronous and asynchronous operations.
Closing Files
CloseHandle
BOOL CloseHandle(HANDLE hObject);
Closes an open object handle, including file handles. It's crucial to close handles when they are no longer needed to release system resources.
Directory Operations
CreateDirectory
BOOL CreateDirectory(LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpAttribute);
Creates a new directory with the specified path. If the parent directory doesn't exist, this function fails.
RemoveDirectory
BOOL RemoveDirectory(LPCTSTR lpPathName);
Deletes an empty directory. The directory must not contain any files or subdirectories.
FindFirstFile
HANDLE FindFirstFile(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData);
Begins the process of searching for files that match a specified pattern (e.g., *.txt) in a directory. Returns a search handle and fills a WIN32_FIND_DATA structure with information about the first file found.
FindNextFile
BOOL FindNextFile(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData);
Continues a file search started by FindFirstFile. Retrieves information about the next file that matches the search pattern.
FindClose
BOOL FindClose(HANDLE hFindFile);
Closes the search handle returned by FindFirstFile and releases associated resources.
File Information
GetFileAttributes
DWORD GetFileAttributes(LPCTSTR lpFileName);
Retrieves the attributes of a specified file or directory. Returns INVALID_FILE_ATTRIBUTES on failure.
SetFileAttributes
BOOL SetFileAttributes(LPCTSTR lpFileName, DWORD dwFileAttributes);
Sets the attributes of a file or directory. Allows modification of flags like read-only, hidden, etc.
Example Usage (Conceptual C++)
Here's a simplified example illustrating how to create a file, write to it, and read from it:
#include <windows.h>
#include <iostream>
#include <string>
int main() {
HANDLE hFile;
DWORD dwBytesWritten;
DWORD dwBytesRead;
char buffer[1024] = {0};
std::string filePath = "example.txt";
std::string fileContent = "Hello from Win32 API!\n";
// Create or open the file
hFile = CreateFile(
filePath.c_str(), // File name
GENERIC_WRITE | GENERIC_READ, // Desired access
0, // Share mode (exclusive access)
NULL, // Security attributes
CREATE_ALWAYS, // Creation disposition (overwrite if exists)
FILE_ATTRIBUTE_NORMAL, // Flags and attributes
NULL // Template file
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Error creating/opening file: " << GetLastError() << std::endl;
return 1;
}
// Write to the file
if (!WriteFile(
hFile, // File handle
fileContent.c_str(), // Buffer to write from
(DWORD)fileContent.length(), // Number of bytes to write
&dwBytesWritten, // Number of bytes written
NULL // Overlapped structure
)) {
std::cerr << "Error writing to file: " << GetLastError() << std::endl;
CloseHandle(hFile);
return 1;
}
std::cout << "Successfully wrote " << dwBytesWritten << " bytes to " << filePath << std::endl;
// Move file pointer to the beginning for reading
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
// Read from the file
if (!ReadFile(
hFile, // File handle
buffer, // Buffer to read into
sizeof(buffer) - 1, // Number of bytes to read
&dwBytesRead, // Number of bytes read
NULL // Overlapped structure
)) {
std::cerr << "Error reading from file: " << GetLastError() << std::endl;
CloseHandle(hFile);
return 1;
}
buffer[dwBytesRead] = '\0'; // Null-terminate the string
std::cout << "Successfully read " << dwBytesRead << " bytes: " << buffer << std::endl;
// Close the file handle
CloseHandle(hFile);
std::cout << "File handle closed." << std::endl;
return 0;
}