Поделиться через


Функция WriteFileEx (fileapi.h)

Записывает данные в указанный файл или на устройство ввода-вывода. Он асинхронно сообщает о состоянии завершения, вызывая указанную подпрограмму завершения, когда запись завершена или отменена, а вызывающий поток находится в состоянии ожидания с возможностью предупреждения.

Для синхронной записи данных в файл или устройство используйте функцию WriteFile .

Синтаксис

BOOL WriteFileEx(
  [in]           HANDLE                          hFile,
  [in, optional] LPCVOID                         lpBuffer,
  [in]           DWORD                           nNumberOfBytesToWrite,
  [in, out]      LPOVERLAPPED                    lpOverlapped,
  [in]           LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Параметры

[in] hFile

Дескриптор файла или устройства ввода-вывода (например, файл, файловый поток, физический диск, том, буфер консоли, ленточный накопитель, сокет, коммуникационный ресурс, почтовый слопот или канал).

Этим параметром может быть любой дескриптор, открытый с флагом FILE_FLAG_OVERLAPPED функцией CreateFile , или дескриптор сокета, возвращаемый функцией сокета или accept .

Не свяжите порт завершения ввода-вывода с этим дескриптором. Дополнительные сведения см. в разделе «Примечания».

Этот дескриптор также должен иметь право доступа к GENERIC_WRITE . Дополнительные сведения о правах доступа см. в разделе Безопасность файлов и права доступа.

[in, optional] lpBuffer

Указатель на буфер, содержащий данные для записи в файл или устройство.

Этот буфер должен оставаться действительным в течение операции записи. Вызывающий объект не должен использовать этот буфер до завершения операции записи.

[in] nNumberOfBytesToWrite

Число байтов, записываемых в файл или устройство.

Нулевое значение указывает операцию записи null. Поведение операции записи null зависит от базовой файловой системы.

Операции записи по каналу в сети ограничены 65 535 байтами на запись. Дополнительные сведения о канале см. в разделе Примечания.

[in, out] lpOverlapped

Указатель на структуру данных OVERLAPPED , которая предоставляет данные для использования во время перекрывающейся (асинхронной) операции записи.

Для файлов, поддерживающих смещение байтов, необходимо указать смещение байтов, с которого начинается запись в файл. Это смещение можно указать, задав элементы Offset и OffsetHigh структуры OVERLAPPED . Для файлов или устройств, которые не поддерживают смещения байтов, Offset и OffsetHigh игнорируются.

Для записи в конец файла укажите члены Offset и OffsetHigh структуры OVERLAPPED как 0xFFFFFFFF. Это функционально эквивалентно вызову функции CreateFile для открытия hFile с помощью FILE_APPEND_DATA доступа.

Функция WriteFileEx игнорирует элемент hEvent структуры OVERLAPPED. Приложение может использовать этот элемент в своих целях в контексте вызова WriteFileEx . WriteFileEx сигнализирует о завершении операции записи путем вызова или постановки в очередь подпрограммы завершения, на которую указывает lpCompletionRoutine, поэтому ей не требуется дескриптор событий.

Функция WriteFileEx использует элементы Internal и InternalHigh структуры OVERLAPPED . Не следует изменять значение этих элементов.

Структура данных OVERLAPPED должна оставаться действительной в течение операции записи. Это не должна быть переменная, которая может выйти из область пока операция записи находится в состоянии ожидания завершения.

[in] lpCompletionRoutine

Указатель на подпрограмму завершения, вызываемую после завершения операции записи, а вызывающий поток находится в состоянии ожидания с возможностью предупреждения. Дополнительные сведения об этой процедуре завершения см. в разделе FileIOCompletionRoutine.

Возвращаемое значение

Если функция выполняется успешно, возвращается ненулевое значение.

Если функция выполняется неудачно, возвращается нулевое значение. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.

Если функция WriteFileEx завершается успешно, вызывающий поток ожидает асинхронной операции ввода-вывода: перекрывающаяся операция записи в файл. Когда эта операция ввода-вывода завершается и вызывающий поток блокируется в состоянии ожидания с оповещениями, операционная система вызывает функцию, на которую указывает lpCompletionRoutine, и ожидание завершается с кодом WAIT_IO_COMPLETIONвозврата .

Если функция выполняется успешно и операция записи файлов завершается, но вызывающий поток не находится в состоянии ожидания с оповещением, система помещает в очередь вызов *lpCompletionRoutine, удерживая вызов до тех пор, пока вызывающий поток не перейдет в состояние ожидания с оповещением. Дополнительные сведения о состояниях ожидания с возможностью оповещения и перекрывающихся операциях ввода-вывода см. в разделе Сведения о синхронизации.

Комментарии

При использовании WriteFileEx следует проверка GetLastError, даже если функция возвращает "success" для проверка для условий, которые являются успешными, но имеют некоторые результаты, о которых вы, возможно, захотите узнать. Например, переполнение буфера при вызове WriteFileEx возвращает TRUE, но GetLastError сообщит о переполнении с ERROR_MORE_DATAпомощью . Если вызов функции выполнен успешно и условия предупреждения отсутствуют, GetLastError вернет ERROR_SUCCESS.

Функция WriteFileEx завершится ошибкой, если параметр hFile связан с портом завершения ввода-вывода. Для выполнения операций записи с помощью этого типа дескриптора используйте функцию WriteFile .

Функция WriteFileEx может завершиться ошибкой, если имеется слишком много невыполненных асинхронных запросов ввода-вывода. В случае такого сбоя GetLastError может вернуть ERROR_INVALID_USER_BUFFER или ERROR_NOT_ENOUGH_MEMORY.

Чтобы отменить все ожидающие асинхронные операции ввода-вывода, используйте один из следующих способов:

  • CancelIo: эта функция отменяет только операции, выданные вызывающим потоком для указанного дескриптора файла.
  • CancelIoEx: эта функция отменяет все операции, выданные потоками для указанного дескриптора файла.

Используйте CancelSynchronousIo для отмены ожидающих синхронных операций ввода-вывода.

Операции ввода-вывода, отмененные с ошибкой ERROR_OPERATION_ABORTED.

Если часть файла, указанная hFile, заблокирована другим процессом, а указанная операция записи перекрывает заблокированную часть, writeFileEx завершается ошибкой.

При записи в файл время последней записи не обновляется полностью, пока не будут закрыты все дескрипторы, используемые для записи. Поэтому, чтобы обеспечить точное время последней записи, закройте дескриптор файла сразу после записи в файл.

Доступ к выходному буферу во время операции записи с использованием буфера может привести к повреждению данных, записанных из этого буфера. Приложения не должны выполнять запись в, перераспределять или освобождать выходной буфер, который используется операцией записи, пока операция записи не завершится.

Обратите внимание, что метки времени могут быть обновлены неправильно для удаленного файла. Чтобы обеспечить согласованность результатов, используйте небуферированные ввод-вывод.

Система интерпретирует ноль байтов для записи как указывающую операцию записи null, и WriteFile не усекает и не расширяет файл. Чтобы усечь или расширить файл, используйте функцию SetEndOfFile .

Приложение использует функции WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx, SignalObjectAndWait и SleepEx для входа в состояние ожидания с оповещениями. Дополнительные сведения о состояниях ожидания с возможностью оповещения и перекрывающихся операциях ввода-вывода см. в разделе Сведения о синхронизации.

При записи непосредственно в том с подключенной файловой системой необходимо сначала получить монопольный доступ к тому. В противном случае вы рискуете привести к повреждению данных или нестабильной работе системы, так как операции записи приложения могут конфликтовать с другими изменениями, поступающими из файловой системы, и оставить содержимое тома в несогласованном состоянии. Чтобы избежать этих проблем, в Windows Vista и более поздних версиях были внесены следующие изменения:

  • Запись в дескриптор тома будет выполнена успешно, если на томе нет подключенной файловой системы или если выполняется одно из следующих условий:
    • Секторы, в которые необходимо записать, являются загрузочными секторами.
    • Секторы, которые необходимо записать, находятся за пределами пространства файловой системы.
    • Вы явно заблокировали или отключили том с помощью FSCTL_LOCK_VOLUME или FSCTL_DISMOUNT_VOLUME.
    • В томе нет фактической файловой системы. (Иными словами, в ней подключена файловая система RAW.)
  • Запись на дескриптор диска будет выполнена успешно, если выполняется одно из следующих условий:
    • Секторы, для записи в которые не попадают в экстенты тома.
    • Секторы, которые необходимо записать в подключенный том, но вы явно заблокировали или отключили том с помощью FSCTL_LOCK_VOLUME или FSCTL_DISMOUNT_VOLUME.
    • Секторы, записываемые в том, не имеют подключенной файловой системы, кроме RAW.

Существуют строгие требования для успешной работы с файлами, открытыми с помощью CreateFile с помощью FILE_FLAG_NO_BUFFERING. Дополнительные сведения см. в разделе Буферизация файлов.

В Windows 8 и Windows Server 2012 эта функция поддерживается следующими технологиями.

Технология Поддерживается
Протокол SMB 3.0 Да
Прозрачная отработка отказа (TFO) SMB 3.0 Да
SMB 3.0 с масштабируемыми общими папками (SO) Да
Файловая система общего тома кластера (CSVFS) Да
Восстанавливаемая файловая система (ReFS) Да

Транзакция операций

При наличии транзакции, привязанной к дескриптору файла, выполняется транзакция записи файла. Дополнительные сведения см. в разделе Сведения о транзакционной NTFS.

Примеры

Пример см. в разделе Сервер именованных каналов, использующий подпрограммы завершения.

Требования

Требование Значение
Минимальная версия клиента Windows XP [классические приложения | Приложения UWP]
Минимальная версия сервера Windows Server 2003 [классические приложения | Приложения UWP]
Целевая платформа Windows
Header fileapi.h (включая Windows.h)
Библиотека Kernel32.lib
DLL Kernel32.dll

См. также