Windows File System Async API Reference

MSDN Community | Exploring Asynchronous File Operations

Asynchronous File Operations (I/O)

This section covers the asynchronous programming model for interacting with the Windows file system. Asynchronous I/O allows your application to initiate an operation and continue executing without waiting for the operation to complete, significantly improving responsiveness and resource utilization.

Overview of Asynchronous I/O

Windows provides several mechanisms for asynchronous file operations. The most common involve:

Core Win32 Functions

CreateFileW with `FILE_FLAG_OVERLAPPED`

To perform asynchronous I/O, you must open the file handle with the FILE_FLAG_OVERLAPPED flag:

HANDLE CreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );

Key parameters when using FILE_FLAG_OVERLAPPED:

OVERLAPPED Structure

The OVERLAPPED structure is central to managing asynchronous operations. It holds information about the pending I/O request, including an event handle that can be signaled upon completion.

typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; union { struct { DWORD Offset; DWORD OffsetHigh; }; PVOID Pointer; }; HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED;

Reading and Writing Asynchronously

Use ReadFile and WriteFile with a populated OVERLAPPED structure for asynchronous operations.

ReadFile

BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped );

WriteFile

BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped );

Checking for Completion

There are several ways to check if an asynchronous I/O operation has completed:

  1. Polling the Event Handle: Use WaitForSingleObject or WaitForMultipleObjects on the OVERLAPPED.hEvent.
  2. Using GetOverlappedResult: This function can wait for the operation to complete or retrieve the status of a pending operation.

GetOverlappedResult

BOOL GetOverlappedResult( HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait );

I/O Completion Ports (IOCP)

For high-performance servers or applications handling many concurrent I/O operations, I/O Completion Ports are the preferred mechanism. They provide a thread-pool management system that efficiently handles I/O completions.

Using IOCP typically involves creating a single completion port, associating file handles with it, and then having multiple worker threads call GetQueuedCompletionStatus to process completed I/O operations.

Note: When using FILE_FLAG_OVERLAPPED, ensure that each asynchronous I/O operation uses its own unique OVERLAPPED structure instance, especially if you are not using I/O Completion Ports.

Monitoring Directory Changes

The ReadDirectoryChangesW function allows you to monitor a directory for changes (creation, deletion, renaming of files).

BOOL ReadDirectoryChangesW( HANDLE hDirectory, LPVOID lpBuffer, DWORD nBufferLength, BOOL bWatchSubtree, DWORD dwNotifyFilter, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );

Tip: For robust asynchronous file system programming, consider using higher-level abstractions provided by libraries or frameworks if your environment supports them (e.g., C++ `` with co-routines, C# `System.IO.FileStream` with `async`/`await`). However, understanding these Win32 APIs is crucial for low-level control and performance tuning.