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

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:

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;
}
            
Note: Always check the return values of file I/O functions. INVALID_HANDLE_VALUE for `CreateFile` and FALSE for `ReadFile`/`WriteFile` indicate an error. Use GetLastError() to retrieve the specific error code.
Warning: Be mindful of buffer overflows when reading from files. Ensure your buffer is large enough to hold the data and always null-terminate the buffer if treating it as a string.

Related Topics