Desktop Functions:

   Smart Device Functions:

Show Recent Changes
Subscribe (RSS)
Misc. Pages
Helpful Tools
Suggested Reading
Website TODO List
Download Visual Studio Add-In

WriteFileGather (kernel32)

C# Signature:

static extern bool WriteFileGather(IntPtr hFile, [Out] FILE_SEGMENT_ELEMENT []
   aSegmentArray, uint nNumberOfBytesToWrite, IntPtr lpReserved,
   [In] ref System.Threading.NativeOverlapped lpOverlapped);


[DllImport("kernel32.dll", SetLastError=true)]
static extern unsafe int WriteFileGather(IntPtr hFile,
  FILE_SEGMENT_ELEMENT* aSegmentArray, int nNumberOfBytesToWrite,
  IntPtr lpReserved, System.Threading.NativeOverlapped* lpOverlapped);

User-Defined Types:

[StructLayout(LayoutKind.Explicit, Size = 8)]
internal struct FILE_SEGMENT_ELEMENT
  public IntPtr Buffer;
  public UInt64 Alignment;


The documentation for the Scatter/Gather functions states that the buffer addresses used must be page aligned (not just storage aligned). Indeed, passing a managed allocation, such as a byte array, causes error 87 (Invalid Parameter). This function is asynchronous only so an use the AsyncResult and Overlapped pattern established by the FileStream.

Tips & Tricks:

It is recommended that VirtualAlloc be used to allocate an unmanaged block of memory for use with this function. The array of file segments can be effeciently constructed without heap allocation using stackalloc. You will need to get the system's page size through a call to GetSystemInfo.

Sample Code:

// Prepares the array of file segments given an IntPtr[] ABuffers (only uses ACount of the buffers so that these arrays can be pooled)
// The size of each buffer (ASize) must be a multiple of the system's page size (get using GetSystemInfo)
int LPerBufferPageCount = ASize / FPageSize;
FILE_SEGMENT_ELEMENT* LElements = stackalloc FILE_SEGMENT_ELEMENT[(ACount * LPerBufferPageCount) + 1];
for (int LElementIndex = 0; LElementIndex < ACount; LElementIndex++)
  for (int LPageIndex = 0; LPageIndex < LPerBufferPageCount; LPageIndex++)
   LElements[(LElementIndex * LPerBufferPageCount) + LPageIndex].Buffer =
    (IntPtr)((uint)ABuffers[LElementIndex] + (LPageIndex * FPageSize));
LElements[(ACount * LPerBufferPageCount)].Buffer = IntPtr.Zero;

Alternative Managed API:

No managed API as of the 1.1 Framework.

See Also



Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

Access directly from VS:
Terms of Use
Edit This Page
Find References
Show Printable Version