How to empty/flush Windows READ disk cache in C#?

Pretzel picture Pretzel · Sep 23, 2008 · Viewed 13.9k times · Source

If I am trying to determine the read speed of a drive, I can code a routine to write files to a filesystem and then read those files back. Unfortunately, this doesn't give an accurate read speed because Windows does disk read caching.

Is there a way to flush the disk read cache of a drive in C# / .Net (or perhaps with Win32 API calls) so that I can read the files directly from the drive without them being cached?

Answer

Pretzel picture Pretzel · Sep 24, 2008

Constantin: Thanks! That link has a command-line EXE which does the testing I was looking for.

I also found a link off that page to a more interesting article (in Word and PDF) on this page: Sequential File Programming Patterns and Performance with .NET

In this article, it talks about Un-buffered File Performance (iow, no read/write caching -- just raw disk performance.)

Quoted directly from the article:

There is no simple way to disable FileStream buffering in the V2 .NET framework. One must invoke the Windows file system directly to obtain an un-buffered file handle and then ‘wrap’ the result in a FileStream as follows in C#:

    [DllImport("kernel32", SetLastError=true)]
    static extern unsafe SafeFileHandle CreateFile(
        string FileName,           // file name
        uint DesiredAccess,        // access mode
        uint ShareMode,            // share mode
        IntPtr SecurityAttributes, // Security Attr
        uint CreationDisposition,  // how to create
        uint FlagsAndAttributes,   // file attributes
        SafeFileHandle  hTemplate // template file  
        );

    SafeFileHandle handle = CreateFile(FileName,
                            FileAccess.Read,
                            FileShare.None,
                            IntPtr.Zero,
                            FileMode.Open,
                             FILE_FLAG_NO_BUFFERING,
                            null);

    FileStream stream = new FileStream(handle, 
                    FileAccess.Read, 
                    true, 
                    4096);

Calling CreateFile() with the FILE_FLAG_NO_BUFFERING flag tells the file system to bypass all software memory caching for the file. The ‘true’ value passed as the third argument to the FileStream constructor indicates that the stream should take ownership of the file handle, meaning that the file handle will automatically be closed when the stream is closed. After this hocus-pocus, the un-buffered file stream is read and written in the same way as any other.