File Creation and Manipulation
This section covers the core Windows API functions for creating, opening, reading, writing, and managing files.
Overview
The Windows API provides a comprehensive set of functions for interacting with the file system. These functions allow applications to perform operations such as creating new files, opening existing ones, reading data from them, writing data to them, and controlling various file attributes and access permissions.
Key Concepts
- File Handles: A file handle is an identifier returned by the operating system when a file is successfully opened or created. It's used in subsequent operations to refer to that specific file.
- CreateFile: This is the primary function for creating or opening files. It allows specifying the desired access modes, sharing modes, security attributes, and flags.
- Reading and Writing: Functions like
ReadFileandWriteFileare used to transfer data between memory buffers and files. - File Pointers: Applications can manipulate the current position within a file using functions like
SetFilePointer. - File Attributes: Files have attributes like hidden, read-only, system, and archive. These can be retrieved and modified using functions like
GetFileAttributesandSetFileAttributes.
Core Functions
Here are some of the most important functions for file creation and manipulation:
CreateFile
Creates or opens a file or I/O device. This is the foundational function for most file operations.
HANDLE CreateFile( LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );Parameters:
- lpFileName: The name of the file or device.
- dwDesiredAccess: The type of access to the file.
GENERIC_READ,GENERIC_WRITE. - dwShareMode: How the file can be shared.
FILE_SHARE_READ,FILE_SHARE_WRITE. - lpSecurityAttributes: Security descriptor for the file.
- dwCreationDisposition: Action to take if the file exists or does not exist.
CREATE_ALWAYS,CREATE_NEW,OPEN_ALWAYS,OPEN_EXISTING,TRUNCATE_EXISTING. - dwFlagsAndAttributes: File attributes and flags.
FILE_ATTRIBUTE_NORMAL. - hTemplateFile: Handle to a template file.
ReadFile
Reads data from a file or I/O device into a buffer.
BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped );WriteFile
Writes data to a file or I/O device.
BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped );CloseHandle
Closes an open object handle. Essential for releasing file resources.
BOOL CloseHandle( HANDLE hObject );SetFilePointer
Moves the file pointer of the specified file to a location within the file.
DWORD SetFilePointer( HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod );GetFileAttributes
Retrieves the attributes of a specified file.
DWORD GetFileAttributes( LPCSTR lpFileName );Code Examples
Here's a simple example demonstrating how to create a file, write to it, and then read from it.
Creating and Writing to a File
#include <windows.h>
#include <iostream>
int main() {
HANDLE hFile;
DWORD dwBytesWritten;
const char* dataToWrite = "Hello, Windows API File I/O!";
const char* filename = "my_test_file.txt";
// Create or open the file
hFile = CreateFile(
filename,
GENERIC_WRITE, // Desired access: write access
0, // Share mode: no sharing
NULL, // Security attributes: default
CREATE_ALWAYS, // Creation disposition: overwrite if exists
FILE_ATTRIBUTE_NORMAL, // Flags and attributes: normal
NULL // Template file: none
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Error creating file: " << GetLastError() << std::endl;
return 1;
}
// Write data to the file
if (!WriteFile(
hFile, // Handle to the file
dataToWrite, // Buffer containing the data
strlen(dataToWrite), // 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 " << filename << std::endl;
// Close the file handle
CloseHandle(hFile);
return 0;
}
Reading from a File
#include <windows.h>
#include <iostream>
#include <vector>
int main() {
HANDLE hFile;
DWORD dwBytesRead;
const char* filename = "my_test_file.txt";
char buffer[256]; // Buffer to store read data
// Open the file for reading
hFile = CreateFile(
filename,
GENERIC_READ, // Desired access: read access
FILE_SHARE_READ, // Share mode: allow others to read
NULL, // Security attributes: default
OPEN_EXISTING, // Creation disposition: open if exists
FILE_ATTRIBUTE_NORMAL, // Flags and attributes: normal
NULL // Template file: none
);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Error opening file: " << GetLastError() << std::endl;
return 1;
}
// Read data from the file
if (ReadFile(
hFile, // Handle to the file
buffer, // Buffer to store data
sizeof(buffer) - 1, // Number of bytes to read (leave space for null terminator)
&dwBytesRead, // Number of bytes read
NULL // Overlapped structure
)) {
buffer[dwBytesRead] = '\0'; // Null-terminate the buffer
std::cout << "Successfully read " << dwBytesRead << " bytes from " << filename << ":" << std::endl;
std::cout << buffer << std::endl;
} else {
std::cerr << "Error reading from file: " << GetLastError() << std::endl;
}
// Close the file handle
CloseHandle(hFile);
return 0;
}
INVALID_HANDLE_VALUE for `CreateFile` and FALSE for `ReadFile`/`WriteFile` indicate an error. Use GetLastError() to retrieve the specific error code.