File Operations

Introduction to File APIs

The Windows operating system provides a comprehensive set of APIs for interacting with files. These APIs allow developers to create, read, write, delete, and manage file attributes. Understanding these functions is crucial for building robust applications that handle data persistence.

This section focuses on the core APIs for file manipulation, covering common operations and best practices.

Common File Operations

Below are some of the most frequently used functions for file operations:

Creating and Opening Files

To interact with a file, you typically need to open it first. The CreateFile function is a versatile API that can create a new file or open an existing one.


HANDLE CreateFile(
  LPCSTR lpFileName,                // File name
  DWORD  dwDesiredAccess,           // Access mode (e.g., GENERIC_READ, GENERIC_WRITE)
  DWORD  dwShareMode,               // Sharing mode
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // Security attributes
  DWORD  dwCreationDisposition,     // How to create or open
  DWORD  dwFlagsAndAttributes,      // File attributes and flags
  HANDLE hTemplateFile              // Handle to template file
);
                

Key parameters include:

  • lpFileName: The path to the file.
  • dwDesiredAccess: Specifies the type of access you want to the file. Use constants like GENERIC_READ and GENERIC_WRITE.
  • dwCreationDisposition: Determines if a file is created, opened, or truncated. Common values are CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXISTING.

Note: Always check the return value of CreateFile. A return value of INVALID_HANDLE_VALUE indicates an error. Use GetLastError() to retrieve the error code.

Reading and Writing File Data

Once a file is opened, you can read from or write to it using ReadFile and WriteFile.


BOOL ReadFile(
  HANDLE       hFile,               // Handle to the file
  LPVOID       lpBuffer,            // Buffer to receive data
  DWORD        nNumberOfBytesToRead, // Number of bytes to read
  LPDWORD      lpNumberOfBytesRead,  // Number of bytes read
  LPOVERLAPPED lpOverlapped          // Overlapped structure (for async I/O)
);

BOOL WriteFile(
  HANDLE       hFile,               // Handle to the file
  LPCVOID      lpBuffer,            // Buffer containing data to write
  DWORD        nNumberOfBytesToWrite, // Number of bytes to write
  LPDWORD      lpNumberOfBytesWritten, // Number of bytes written
  LPOVERLAPPED lpOverlapped         // Overlapped structure (for async I/O)
);
                

These functions are synchronous by default. For asynchronous operations, you can use the lpOverlapped parameter.

Closing Files

It is essential to close file handles when you are finished with them to release system resources and ensure data is flushed to disk.


BOOL CloseHandle(
  HANDLE hObject // Handle to the object
);
                

Deleting Files

The DeleteFile function removes a file from the file system.


BOOL DeleteFile(
  LPCSTR lpFileName // File name
);
                

Warning: Files deleted using DeleteFile are permanently removed and cannot be recovered without specialized tools.

File Attributes and Metadata

Windows files have attributes that provide information about their state, such as whether they are read-only, hidden, or archived. You can get and set these attributes using specific APIs.

Getting File Attributes


DWORD GetFileAttributes(
  LPCSTR lpFileName // File name
);
                

This function returns a bitmask of file attribute flags (e.g., FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_HIDDEN).

Setting File Attributes


BOOL SetFileAttributes(
  LPCSTR lpFileName,       // File name
  DWORD  dwFileAttributes // New file attributes
);
                

Error Handling

Proper error handling is paramount when working with file system APIs. Most Windows API functions that can fail return specific error codes. The GetLastError() function retrieves the most recent error code set by a failed API call.


DWORD error = GetLastError();
// Use FormatMessage to get a human-readable string for the error code.