Memory-mapping is my preferred way to do file I/O, on pretty much every platform I write code for (desktop and console). In this post, we’ll start by discussing some of the key advantages of this approach, as well as some disadvantages. Then, we’ll look at some Windows-specific undocumented user-mode functions which help mitigate some of those disadvantages. In particular, we’ll address an important perceived limitation of memory-mapped I/O, namely, file resizing.
Note that this post is largely an amalgamation of various notes I’ve collected over the years, so some parts of this post aren’t well-structured into a linear narrative. Also, I am in no way suggesting that memory-mapping is a panacea for all file I/O needs. Memory-mapped I/O has, however, served me well for my use-cases, so consider the pros and cons for your particular needs and users.
In this example, we’re sticking to a read-only file, but a mutable memory mapped file is easy to achieve with different protection and access bits.