WriteFile function (fileapi.h)
Writes data to the specified file or input/output (I/O) device.
This function is designed for both synchronous and asynchronous operation. For a similar function designed solely for asynchronous operation, see WriteFileEx.
Syntax
Parameters
A handle to the file or I/O device (for example, a file, file stream, physical disk, volume, console buffer, tape drive, socket, communications resource, mailslot, or pipe).
The hFile parameter must have been created with the write access. For more information, see Generic Access Rights and File Security and Access Rights.
For asynchronous write operations, hFile can be any handle opened with the CreateFile function using the FILE_FLAG_OVERLAPPED flag or a socket handle returned by the socket or accept function.
A pointer to the buffer containing the data to be written to the file or device.
This buffer must remain valid for the duration of the write operation. The caller must not use this buffer until the write operation is completed.
The number of bytes to be written to the file or device.
A value of zero specifies a null write operation. The behavior of a null write operation depends on the underlying file system or communications technology.
Windows ServerВ 2003 and WindowsВ XP:В В Pipe write operations across a network are limited in size per write. The amount varies per platform. For x86 platforms it’s 63.97 MB. For x64 platforms it’s 31.97 MB. For Itanium it’s 63.95 MB. For more information regarding pipes, see the Remarks section.
A pointer to the variable that receives the number of bytes written when using a synchronous hFile parameter. WriteFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.
This parameter can be NULL only when the lpOverlapped parameter is not NULL.
For more information, see the Remarks section.
A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL.
For an hFile that supports byte offsets, if you use this parameter you must specify a byte offset at which to start writing to the file or device. This offset is specified by setting the Offset and OffsetHigh members of the OVERLAPPED structure. For an hFile that does not support byte offsets, Offset and OffsetHigh are ignored.
To write to the end of file, specify both the Offset and OffsetHigh members of the OVERLAPPED structure as 0xFFFFFFFF. This is functionally equivalent to previously calling the CreateFile function to open hFile using FILE_APPEND_DATA access.
For more information about different combinations of lpOverlapped and FILE_FLAG_OVERLAPPED, see the Remarks section and the Synchronization and File Position section.
Return value
If the function succeeds, the return value is nonzero (TRUE).
If the function fails, or is completing asynchronously, the return value is zero (FALSE). To get extended error information, call the GetLastError function.
Remarks
The WriteFile function returns when one of the following conditions occur:
- The number of bytes requested is written.
- A read operation releases buffer space on the read end of the pipe (if the write was blocked). For more information, see the Pipes section.
- An asynchronous handle is being used and the write is occurring asynchronously.
- An error occurs.
The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.
To cancel all pending asynchronous I/O operations, use either:
- CancelIo—this function cancels only operations issued by the calling thread for the specified file handle.
- CancelIoEx—this function cancels all operations issued by the threads for the specified file handle.
Use the CancelSynchronousIo function to cancel pending synchronous I/O operations.
I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.
The WriteFile function may fail with ERROR_NOT_ENOUGH_QUOTA, which means the calling process’s buffer could not be page-locked. For more information, see SetProcessWorkingSetSize.
If part of the file is locked by another process and the write operation overlaps the locked portion, WriteFile fails.
When writing to a file, the last write time is not fully updated until all handles used for writing have been closed. Therefore, to ensure an accurate last write time, close the file handle immediately after writing to the file.
Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not write to, reallocate, or free the output buffer that a write operation is using until the write operation completes. This can be particularly problematic when using an asynchronous file handle. Additional information regarding synchronous versus asynchronous file handles can be found later in the Synchronization and File Position section and Synchronous and Asynchronous I/O.
Note that the time stamps may not be updated correctly for a remote file. To ensure consistent results, use unbuffered I/O.
The system interprets zero bytes to write as specifying a null write operation and WriteFile does not truncate or extend the file. To truncate or extend a file, use the SetEndOfFile function.
Characters can be written to the screen buffer using WriteFile with a handle to console output. The exact behavior of the function is determined by the console mode. The data is written to the current cursor position. The cursor position is updated after the write operation. For more information about console handles, see CreateFile.
When writing to a communications device, the behavior of WriteFile is determined by the current communication time-out as set and retrieved by using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable results can occur if you fail to set the time-out values. For more information about communication time-outs, see COMMTIMEOUTS.
Although a single-sector write is atomic, a multi-sector write is not guaranteed to be atomic unless you are using a transaction (that is, the handle created is a transacted handle; for example, a handle created using CreateFileTransacted). Multi-sector writes that are cached may not always be written to the disk right away; therefore, specify FILE_FLAG_WRITE_THROUGH in CreateFile to ensure that an entire multi-sector write is written to the disk without potential caching delays.
If you write directly to a volume that has a mounted file system, you must first obtain exclusive access to the volume. Otherwise, you risk causing data corruption or system instability, because your application’s writes may conflict with other changes coming from the file system and leave the contents of the volume in an inconsistent state. To prevent these problems, the following changes have been made in WindowsВ Vista and later:
- A write on a volume handle will succeed if the volume does not have a mounted file system, or if one of the following conditions is true:
- The sectors to be written to are boot sectors.
- The sectors to be written to reside outside of file system space.
- You have explicitly locked or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.
- The volume has no actual file system. (In other words, it has a RAW file system mounted.)
- A write on a disk handle will succeed if one of the following conditions is true:
- The sectors to be written to do not fall within a volume’s extents.
- The sectors to be written to fall within a mounted volume, but you have explicitly locked or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.
- The sectors to be written to fall within a volume that has no mounted file system other than RAW.
There are strict requirements for successfully working with files opened with CreateFile using FILE_FLAG_NO_BUFFERING. For details see File Buffering.
If hFile was opened with FILE_FLAG_OVERLAPPED, the following conditions are in effect:
- The lpOverlapped parameter must point to a valid and unique OVERLAPPED structure, otherwise the function can incorrectly report that the write operation is complete.
- The lpNumberOfBytesWritten parameter should be set to NULL. To get the number of bytes written, use the GetOverlappedResult function. If the hFile parameter is associated with an I/O completion port, you can also get the number of bytes written by calling the GetQueuedCompletionStatus function.
In Windows ServerВ 2012, this function is supported by the following technologies.
Technology | Supported |
---|---|
Server Message Block (SMB) 3.0 protocol | Yes |
SMB 3.0 Transparent Failover (TFO) | Yes |
SMB 3.0 with Scale-out File Shares (SO) | Yes |
Cluster Shared Volume File System (CsvFS) | Yes |
Resilient File System (ReFS) | Yes |
В
Synchronization and File Position
Pipes
If the pipe buffer is full when an application uses the WriteFile function to write to a pipe, the write operation may not finish immediately. The write operation will be completed when a read operation (using the ReadFile function) makes more system buffer space available for the pipe.
When writing to a non-blocking, byte-mode pipe handle with insufficient buffer space, WriteFile returns TRUE with *lpNumberOfBytesWritten —>
Performance tuning for file servers
You should select the proper hardware to satisfy the expected file server load, considering average load, peak load, capacity, growth plans, and response times. Hardware bottlenecks limit the effectiveness of software tuning.
General tuning parameters for clients
The following REG_DWORD registry settings can affect the performance of client computers that interact with SMB file servers:
ConnectionCountPerNetworkInterface
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows Server 2016, Windows ServerВ 2012 R2, and Windows ServerВ 2012
The default is 1, and we strongly recommend using the default. The valid range is 1-16. The maximum number of connections per interface to be established with a server for non-RSS interfaces.
ConnectionCountPerRssNetworkInterface
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows Server 2016, Windows ServerВ 2012 R2, and Windows ServerВ 2012
The default is 4, and we strongly recommend using the default. The valid range is 1-16. The maximum number of connections per interface to be established with a server for RSS interfaces.
ConnectionCountPerRdmaNetworkInterface
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows Server 2016, Windows ServerВ 2012 R2, and Windows ServerВ 2012
The default is 2, and we strongly recommend using the default. The valid range is 1-16. The maximum number of connections per interface to be established with a server for RDMA interfaces.
MaximumConnectionCountPerServer
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows Server 2016, Windows ServerВ 2012 R2, and Windows ServerВ 2012
The default is 32, with a valid range from 1-64. The maximum number of connections to be established with a single server running Windows ServerВ 2012 across all interfaces.
DormantDirectoryTimeout
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows Server 2016, Windows ServerВ 2012 R2, and Windows ServerВ 2012
The default is 600 seconds. The maximum time server directory handles held open with directory leases.
FileInfoCacheLifetime
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 10 seconds. The file information cache timeout period.
DirectoryCacheLifetime
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 10 seconds. This is the directory cache timeout.
This parameter controls caching of directory metadata in the absence of directory leases.
A known issue in Windows 10, version 1803, affects the ability of Windows 10 to cache large directories. After you upgrade a computer to Windows 10, version 1803, you access a network share that contains thousands of files and folders, and you open a document that is located on that share. During both of these operations, you experience significant delays.
To resolve this issue, install Windows 10, version 1809 or a later version.
To work around this issue, set DirectoryCacheLifetime to 0.
This issue affects the following editions of Windows 10:
- Windows 10 Enterprise, version 1803
- Windows 10 Pro for Workstations, version 1803
- Windows 10 Pro Education, version 1803
- Windows 10 Professional, version 1803
- Windows 10 Education, version 1803
- Windows 10 Home, version 1803
DirectoryCacheEntrySizeMax
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 64В KB. This is the maximum size of directory cache entries.
FileNotFoundCacheLifetime
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 5 seconds. The file not found cache timeout period.
CacheFileTimeout
Applies to WindowsВ 8.1, WindowsВ 8, Windows ServerВ 2012, Windows ServerВ 2012В R2, and Windows 7
The default is 10 seconds. This setting controls the length of time (in seconds) that the redirector will hold on to cached data for a file after the last handle to the file is closed by an application.
DisableBandwidthThrottling
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 0. By default, the SMB redirector throttles throughput across high-latency network connections, in some cases to avoid network-related timeouts. Setting this registry value to 1 disables this throttling, enabling higher file transfer throughput over high-latency network connections.
DisableLargeMtu
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 0 for Windows 8 only. In Windows 8, the SMB redirector transfers payloads as large as 1В MB per request, which can improve file transfer speed. Setting this registry value to 1 limits the request size to 64В KB. You should evaluate the impact of this setting before applying it.
RequireSecuritySignature
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 0, disabling SMB Signing. Changing this value to 1 enables SMB signing for all SMB communication, preventing SMB communication with computers where SMB signing is disabled. SMB signing can increase CPU cost and network round trips, but helps block man-in-the-middle attacks. If SMB signing is not required, ensure that this registry value is 0 on all clients and servers.
FileInfoCacheEntriesMax
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 64, with a valid range of 1 to 65536. This value is used to determine the amount of file metadata that can be cached by the client. Increasing the value can reduce network traffic and increase performance when a large number of files are accessed.
DirectoryCacheEntriesMax
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 16, with a valid range of 1 to 4096. This value is used to determine the amount of directory information that can be cached by the client. Increasing the value can reduce network traffic and increase performance when large directories are accessed.
FileNotFoundCacheEntriesMax
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 128, with a valid range of 1 to 65536. This value is used to determine the amount of file name information that can be cached by the client. Increasing the value can reduce network traffic and increase performance when a large number of file names are accessed.
MaxCmds
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 15. This parameter limits the number of outstanding requests on a session. Increasing the value can use more memory, but it can improve performance by enabling a deeper request pipeline.В Increasing the value in conjunction with MaxMpxCt can also eliminate errors that are encountered due to large numbers of outstanding long-term file requests, such as FindFirstChangeNotification calls. This parameter does not affect connections with SMB 2.0 servers.
DormantFileLimit
Applies to WindowsВ 10, Windows 8.1, WindowsВ 8, Windows 7, Windows Vista, Windows Server 2016, Windows ServerВ 2012 R2, Windows ServerВ 2012, Windows Server 2008 R2, and Windows Server 2008
The default is 1023. This parameter specifies the maximum number of files that should be left open on a shared resource after the application has closed the file.
Client tuning example
The general tuning parameters for client computers can optimize a computer for accessing remote file shares, particularly over some high-latency networks (such as branch offices, cross-datacenter communication, home offices, and mobile broadband). The settings are not optimal or appropriate on all computers. You should evaluate the impact of individual settings before applying them.
Parameter | Value | Default |
---|---|---|
DisableBandwidthThrottling | 1 | 0 |
FileInfoCacheEntriesMax | 32768 | 64 |
DirectoryCacheEntriesMax | 4096 | 16 |
FileNotFoundCacheEntriesMax | 32768 | 128 |
MaxCmds | 32768 | 15 |
Starting in WindowsВ 8, you can configure many of these SMB settings by using the Set-SmbClientConfiguration and Set-SmbServerConfiguration Windows PowerShell cmdlets. Registry-only settings can be configured by using Windows PowerShell as well.