다음을 통해 공유


WriteFileEx 함수(fileapi.h)

지정된 파일 또는 I/O(입출력) 디바이스에 데이터를 씁니다. 쓰기가 완료 또는 취소되고 호출 스레드가 경고 대기 상태에 있을 때 완료 상태를 비동기적으로 보고하고, 지정된 완료 루틴을 호출합니다.

파일 또는 디바이스에 데이터를 동기적으로 쓰려면 WriteFile 함수를 사용합니다.

구문

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

매개 변수

[in] hFile

파일 또는 I/O 디바이스에 대한 핸들(예: 파일, 파일 스트림, 실제 디스크, 볼륨, 콘솔 버퍼, 테이프 드라이브, 소켓, 통신 리소스, mailslot 또는 파이프).

이 매개 변수는 CreateFile 함수에서 FILE_FLAG_OVERLAPPED 플래그로 연 핸들 또는 소켓 또는 accept 함수에서 반환된 소켓 핸들일 수 있습니다.

I/O 완료 포트를 이 핸들과 연결하지 마세요. 자세한 내용은 주의 섹션을 참조하세요.

또한 이 핸들에는 GENERIC_WRITE 액세스 권한이 있어야 합니다. 액세스 권한에 대한 자세한 내용은 파일 보안 및 액세스 권한을 참조하세요.

[in, optional] lpBuffer

파일 또는 디바이스에 쓸 데이터를 포함하는 버퍼에 대한 포인터입니다.

이 버퍼는 쓰기 작업 기간 동안 유효한 상태로 유지되어야 합니다. 호출자는 쓰기 작업이 완료될 때까지 이 버퍼를 사용하면 안됩니다.

[in] nNumberOfBytesToWrite

파일 또는 디바이스에 쓸 바이트 수입니다.

값이 0이면 null 쓰기 작업이 지정됩니다. null 쓰기 작업의 동작은 기본 파일 시스템에 따라 달라집니다.

네트워크를 통해 파이프 쓰기 작업은 쓰기당 65,535바이트로 제한됩니다. 파이프에 대한 자세한 내용은 설명 섹션을 참조하세요.

[in, out] lpOverlapped

겹치는(비동기) 쓰기 작업 중에 사용할 데이터를 제공하는 OVERLAPPED 데이터 구조에 대한 포인터입니다.

바이트 오프셋을 지원하는 파일의 경우 파일에 쓰기를 시작할 바이트 오프셋을 지정해야 합니다. OVERLAPPED 구조체의 OffsetOffsetHigh 멤버를 설정하여 이 오프셋을 지정합니다. 바이트 오프셋을 지원하지 않는 파일 또는 디바이스의 경우 Offset 및 OffsetHigh는 무시됩니다.

파일 끝에 쓰려면 OVERLAPPED 구조체의 OffsetOffsetHigh 멤버를 모두 로 0xFFFFFFFF지정합니다. 이는 이전에 CreateFile 함수를 호출하여 FILE_APPEND_DATA 액세스를 사용하여 hFile을 여는 것과 기능적으로 동일합니다.

WriteFileEx 함수는 OVERLAPPED 구조체의 hEvent 멤버를 무시합니다. 애플리케이션은 WriteFileEx 호출의 컨텍스트에서 자체 용도로 해당 멤버를 자유롭게 사용할 수 있습니다. WriteFileExlpCompletionRoutine이 가리키는 완료 루틴을 호출하거나 호출을 큐에 대기하여 쓰기 작업의 완료를 알리므로 이벤트 핸들이 필요하지 않습니다.

WriteFileEx 함수는 OVERLAPPED 구조체의 InternalInternalHigh 멤버를 사용합니다. 이러한 멤버의 값을 변경하면 안 됩니다.

OVERLAPPED 데이터 구조는 쓰기 작업 기간 동안 유효한 상태로 유지되어야 합니다. 쓰기 작업이 완료될 때까지 scope 벗어날 수 있는 변수가 아니어야 합니다.

[in] lpCompletionRoutine

쓰기 작업이 완료되고 호출 스레드가 경고 대기 상태에 있을 때 호출할 완료 루틴에 대한 포인터입니다. 이 완료 루틴에 대한 자세한 내용은 FileIOCompletionRoutine을 참조하세요.

반환 값

함수가 성공하면 반환 값이 0이 아닙니다.

함수가 실패하면 반환 값은 0입니다. 확장 오류 정보를 가져오려면 GetLastError를 호출합니다.

WriteFileEx 함수가 성공하면 호출 스레드에 파일에 겹치는 쓰기 작업인 보류 중인 비동기 I/O 작업이 있습니다. 이 I/O 작업이 완료되고 호출 스레드가 경고 대기 상태에서 차단되면 운영 체제는 lpCompletionRoutine이 가리키는 함수를 호출하고 대기는 의 WAIT_IO_COMPLETION반환 코드로 완료됩니다.

함수가 성공하고 파일 쓰기 작업이 완료되었지만 호출 스레드가 경고 대기 상태가 아닌 경우 시스템은 *lpCompletionRoutine에 대한 호출을 큐에 대기하고 호출 스레드가 경고 대기 상태가 될 때까지 호출을 유지합니다. 경고 가능한 대기 상태 및 겹치는 입력/출력 작업에 대한 자세한 내용은 동기화 정보를 참조하세요.

설명

WriteFileEx를 사용하는 경우 함수가 "성공"을 반환하여 성공했지만 알고 싶은 결과가 있는 조건에 대해 검사 경우에도 GetLastError를 검사 합니다. 예를 들어 WriteFileEx 를 호출할 때 버퍼 오버플로는 를 반환 TRUE하지만 GetLastError 는 를 사용하여 ERROR_MORE_DATA오버플로를 보고합니다. 함수 호출이 성공하고 경고 조건이 없는 경우 GetLastError 는 를 반환 ERROR_SUCCESS합니다.

hFile 매개 변수가 I/O 완성 포트와 연결된 경우 WriteFileEx 함수가 실패합니다. 이 유형의 핸들을 사용하여 쓰기를 수행하려면 WriteFile 함수를 사용합니다.

미해결 비동기 I/O 요청이 너무 많은 경우 WriteFileEx 함수가 실패할 수 있습니다. 이러한 오류가 발생할 경우 GetLastError 는 또는 를 반환 ERROR_INVALID_USER_BUFFERERROR_NOT_ENOUGH_MEMORY수 있습니다.

보류 중인 모든 비동기 I/O 작업을 취소하려면 다음 중 하나를 사용합니다.

  • CancelIo: 이 함수는 지정된 파일 핸들에 대해 호출 스레드에서 발급한 작업만 취소합니다.
  • CancelIoEx: 이 함수는 지정된 파일 핸들에 대해 스레드에서 발급한 모든 작업을 취소합니다.

보류 중인 동기 I/O 작업을 취소하려면 CancelSynchronousIo를 사용하세요.

취소된 I/O 작업은 오류 ERROR_OPERATION_ABORTED 완료됩니다.

hFile에서 지정한 파일의 일부가 다른 프로세스에 의해 잠겨 있고 지정된 쓰기 작업이 잠긴 부분과 겹치면 WriteFileEx가 실패합니다.

파일에 쓸 때 쓰기에 사용되는 모든 핸들이 닫히기 전까지는 마지막 쓰기 시간이 완전히 업데이트되지 않습니다. 따라서 정확한 마지막 쓰기 시간을 보장하려면 파일에 쓴 직후에 파일 핸들을 닫습니다.

쓰기 작업이 버퍼를 사용하는 동안 출력 버퍼에 액세스하면 해당 버퍼에서 작성된 데이터가 손상될 수 있습니다. 애플리케이션은 쓰기 작업이 완료될 때까지 쓰기 작업에서 사용하는 출력 버퍼를 쓰기, 재할당 또는 해제해서는 안 됩니다.

원격 파일에 대한 타임스탬프를 올바르게 업데이트하지 못할 수 있습니다. 일관된 결과를 보장하려면 버퍼가 없는 I/O를 사용합니다.

시스템은 0바이트를 쓰기로 null 쓰기 작업을 지정하는 것으로 해석하고 WriteFile 은 파일을 자르거나 확장하지 않습니다. 파일을 자르거나 확장하려면 SetEndOfFile 함수를 사용합니다.

애플리케이션은 WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx, SignalObjectAndWaitSleepEx 함수를 사용하여 경고 대기 상태를 입력합니다. 경고 가능한 대기 상태 및 겹치는 I/O 작업에 대한 자세한 내용은 동기화 정보를 참조하세요.

탑재된 파일 시스템이 있는 볼륨에 직접 쓰는 경우 먼저 볼륨에 대한 단독 액세스 권한을 얻어야 합니다. 그렇지 않으면 애플리케이션의 쓰기가 파일 시스템에서 오는 다른 변경 내용과 충돌하여 볼륨의 내용이 일관되지 않은 상태로 남을 수 있으므로 데이터 손상 또는 시스템 불안정이 발생할 위험이 있습니다. 이러한 문제를 방지하기 위해 Windows Vista 이상에서 다음과 같이 변경되었습니다.

  • 볼륨에 탑재된 파일 시스템이 없거나 다음 조건 중 하나가 true이면 볼륨 핸들에 대한 쓰기가 성공합니다.
    • 기록할 섹터는 부팅 섹터입니다.
    • 파일 시스템 공간 외부에 상주하도록 작성할 섹터입니다.
    • FSCTL_LOCK_VOLUME 또는FSCTL_DISMOUNT_VOLUME 사용하여 볼륨을 명시적으로 잠그거나 분리했습니다.
    • 볼륨에 실제 파일 시스템이 없습니다. 즉, RAW 파일 시스템이 탑재되어 있습니다.
  • 다음 조건 중 하나가 true이면 디스크 핸들에 대한 쓰기가 성공합니다.
    • 기록할 섹터는 볼륨의 범위 내에 속하지 않습니다.
    • 기록할 섹터는 탑재된 볼륨에 속하지만 FSCTL_LOCK_VOLUME 또는FSCTL_DISMOUNT_VOLUME 사용하여 명시적으로 볼륨을 잠그거나 분리했습니다.
    • RAW 이외의 탑재된 파일 시스템이 없는 볼륨에 속하도록 작성할 섹터입니다.

FILE_FLAG_NO_BUFFERING 사용하여 CreateFile에서 열린 파일을 성공적으로 사용하기 위한 엄격한 요구 사항이 있습니다. 자세한 내용은 파일 버퍼링을 참조하세요.

Windows 8 및 Windows Server 2012에서 이 함수는 다음 기술을 통해 지원됩니다.

기술 지원됨
SMB(서버 메시지 블록) 3.0 프로토콜 Yes
SMB 3.0 TFO(투명 장애 조치(failover)) Yes
SO(스케일 아웃 파일 공유)를 사용하는 SMB 3.0 Yes
CsvFS(클러스터 공유 볼륨 파일 시스템) Yes
ReFS(Resilient File System) Yes

거래된 작업

파일 핸들에 바인딩된 트랜잭션이 있는 경우 파일 쓰기가 트랜잭션됩니다. 자세한 내용은 트랜잭션 NTFS 정보를 참조하세요.

예제

예제는 완료 루틴을 사용하여 명명된 파이프 서버를 참조하세요.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows XP [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 fileapi.h(Windows.h 포함)
라이브러리 Kernel32.lib
DLL Kernel32.dll

참고 항목