This article was previously published under Q99794
The FILE_FLAG_WRITE_THROUGH flag for CreateFile() causes any writes made tothat handle to be written directly to the file without being buffered. Thedata is cached (stored in the disk cache); however, it is still writtendirectly to the file. This method allows a read operation on that data tosatisfy the read request from cached data (if it's still there), ratherthan having to do a file read to get the data. The write call doesn'treturn until the data is written to the file. This applies to remote writesas well--the network redirector passes the FILE_FLAG_WRITE_THROUGH flag tothe server so that the server knows not to satisfy the write request untilthe data is written to the file.

The FILE_FLAG_NO_BUFFERING takes this concept one step further andeliminates all read-ahead file buffering and disk caching as well, so thatall reads are guaranteed to come from the file and not from any systembuffer or disk cache. When using FILE_FLAG_NO_BUFFERING, disk reads andwrites must be done on sector boundaries, and buffer addresses must bealigned on disk sector boundaries in memory.

These restrictions are necessary because the buffer that you pass to theread or write API is used directly for I/O at the device level; at thatlevel, your buffer addresses and sector sizes must satisfy any processorand media alignment restrictions of the hardware you are running on.
The Windows 95 CDFS (CD-ROM File System) does not support theFILE_FLAG_NO_BUFFERING flag for CreateFile(). While a Windows 95 FSD, suchas VFAT, may implement it, FILE_FLAG_NO_BUFFERING is not a required flagfor file system drivers, and it is not supported by CDFS.

This code fragment demonstrates how to sector-align data in a buffer andpass it to CreateFile():
  char buf[2 * SECTOR_SIZE - 1], *p;  p = (char *) ((DWORD) (buf + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1));  h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);  WriteFile(h, p, SECTOR_SIZE, &dwWritten, NULL);				
The pointer p is sector-aligned and points within the buffer.

If you have a situation where you want to flush all open files on thecurrent logical drive, this can be done by:
   hFile = CreateFile("\\\\.\\c:", ....);   FlushFileBuffers(hFile);				
This method causes all buffered write data for all open files on the C:partition to be flushed and written to the disk. Note that any bufferingdone by anything other than the system is not affected by this flush; anypossible file buffering that the C Run-time is doing on files opened with CRun-time routines is unaffected.

When opening a remote file over the network, the server always caches andignores the no buffering flag specified by the client. This is by design.The redirector and server cannot properly implement the full semantics ofFILE_FLAG_NO_BUFFERING over the network. In particular, the requirement forsector-sized, sector-aligned I/O cannot be met. Therefore, when a Win32-based application asks for FILE_FLAG_NO_BUFFERING, the redirector andserver treat this as a request for FILE_FLAG_WRITE_THROUGH. The file is notcached at the client, writes go directly to the server and to the disk onthe server, and the read/write sizes on the network are exactly what theapplication asks for. However, the file is cached on the server.

Not caching the client can have a different effect, depending on the typeof I/O. You eliminate the cache hits or read ahead, but you also may reducethe size of transmits and receives. In general, for sequential I/O, it is agood idea to cache on the client. For small, random access I/O, it is oftenbest not to cache.

Article ID: 99794 - Last Review: 11/21/2006 15:48:00 - Revision: 4.2

Microsoft Win32 Application Programming Interface

  • kbinfo kbapi kbkernbase kbfileio KB99794