다음을 통해 공유


WriteFile 함수(fileapi.h)

지정된 파일 또는 I/O(입출력) 디바이스에 데이터를 씁니다.

이 함수는 동기 및 비동기 작업 모두를 위해 설계되었습니다. 비동기 작업만을 위해 설계된 유사한 함수는 WriteFileEx참조하세요.

통사론

BOOL WriteFile(
  [in]                HANDLE       hFile,
  [in]                LPCVOID      lpBuffer,
  [in]                DWORD        nNumberOfBytesToWrite,
  [out, optional]     LPDWORD      lpNumberOfBytesWritten,
  [in, out, optional] LPOVERLAPPED lpOverlapped
);

매개 변수

[in] hFile

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

hFile 매개 변수는 쓰기 액세스 권한으로 만들어졌어야 합니다. 자세한 내용은 일반 액세스 권한파일 보안 및 액세스 권한참조하세요.

비동기 쓰기 작업의 경우 hFile FILE_FLAG_OVERLAPPED 플래그 또는 소켓 반환된 소켓 핸들을 사용하여 CreateFile 함수로 연 핸들이거나 함수를 수락할 있습니다.

[in] lpBuffer

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

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

[in] nNumberOfBytesToWrite

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

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

Windows Server 2003 및 Windows XP: 네트워크 간 파이프 쓰기 작업은 쓰기당 크기가 제한됩니다. 금액은 플랫폼마다 다릅니다. x86 플랫폼의 경우 63.97MB입니다. x64 플랫폼의 경우 31.97MB입니다. Itanium의 경우 63.95MB입니다. 파이프에 대한 자세한 내용은 설명 섹션을 참조하세요.

[out, optional] lpNumberOfBytesWritten

동기 hFile 매개 변수를 사용할 때 쓴 바이트 수를 받는 변수에 대한 포인터입니다. WriteFile 작업 또는 오류 검사를 수행하기 전에 이 값을 0으로 설정합니다. 잠재적으로 잘못된 결과를 방지하기 위해 비동기 작업인 경우 이 매개 변수에 NULL 사용합니다.

이 매개 변수는 lpOverlapped 매개 변수가 NULL않은 경우에만 NULL 수 있습니다.

Windows 7: 이 매개 변수는 NULL수 없습니다.

자세한 내용은 설명 섹션을 참조하세요.

[in, out, optional] lpOverlapped

FILE_FLAG_OVERLAPPEDhFile 매개 변수를 연 경우 OVERLAPPED 구조체에 대한 포인터가 필요하며, 그렇지 않으면 이 매개 변수를 NULL수 있습니다.

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

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

lpOverlappedFILE_FLAG_OVERLAPPED다양한 조합에 대한 자세한 내용은 설명 섹션 및 동기화 및 파일 위치 섹션을 참조하세요.

반환 값

함수가 성공하면 반환 값은 0이 아닌 값(TRUE)입니다.

함수가 실패하거나 비동기적으로 완료되는 경우 반환 값은 0(FALSE)입니다. 확장 오류 정보를 얻으려면 GetLastError 함수를 호출합니다.

참고GetLastError 코드 ERROR_IO_PENDING 오류가 아닙니다. 쓰기 작업이 비동기적으로 완료 보류 중임을 지정합니다. 자세한 내용은 비고를 참조하세요.
 

발언

WriteFile 함수는 다음 조건 중 하나가 발생하면 반환됩니다.

  • 요청된 바이트 수가 기록됩니다.
  • 읽기 작업은 파이프의 읽기 끝에 버퍼 공간을 해제합니다(쓰기가 차단된 경우). 자세한 내용은 파이프 섹션을 참조하세요.
  • 비동기 핸들이 사용되고 있으며 쓰기가 비동기적으로 발생합니다.
  • 오류가 발생합니다.
WriteFile 함수는 미해결 비동기 I/O 요청이 너무 많을 때마다 ERROR_INVALID_USER_BUFFER 또는 ERROR_NOT_ENOUGH_MEMORY 실패할 수 있습니다.

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

  • CancelIo- 이 함수는 지정된 파일 핸들에 대해 호출 스레드에서 발급한 작업만 취소합니다.
  • CancelIoEx- 이 함수는 지정된 파일 핸들에 대해 스레드에서 발급한 모든 작업을 취소합니다.
CancelSynchronousIo 함수를 사용하여 보류 중인 동기 I/O 작업을 취소합니다.

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

WriteFile 함수는 ERROR_NOT_ENOUGH_QUOTA실패할 수 있습니다. 즉, 호출 프로세스의 버퍼를 페이지로 잠글 수 없습니다. 자세한 내용은 SetProcessWorkingSetSize참조하세요.

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

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

쓰기 작업이 버퍼를 사용하는 동안 출력 버퍼에 액세스하면 해당 버퍼에서 작성된 데이터가 손상될 수 있습니다. 애플리케이션은 쓰기 작업이 완료될 때까지 쓰기 작업이 사용 중인 출력 버퍼에 쓰거나 다시 할당하거나 해제해서는 안 됩니다. 비동기 파일 핸들을 사용할 때 특히 문제가 될 수 있습니다. 동기 및 비동기 파일 핸들에 대한 추가 정보는 동기화 및 파일 위치 섹션과 동기 및 비동기 I/O뒷부분에서 확인할 수 있습니다.

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

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

콘솔 출력에 대한 핸들이 있는 WriteFile 사용하여 화면 버퍼에 문자를 쓸 수 있습니다. 함수의 정확한 동작은 콘솔 모드에 따라 결정됩니다. 데이터는 현재 커서 위치에 기록됩니다. 커서 위치는 쓰기 작업 후에 업데이트됩니다. 콘솔 핸들에 대한 자세한 내용은 CreateFile참조하세요.

통신 디바이스에 쓸 때 WriteFile 동작은 SetCommTimeoutsGetCommTimeouts 함수를 사용하여 설정된 현재 통신 시간 제한에 따라 결정되고 검색됩니다. 제한 시간 값을 설정하지 못하면 예측할 수 없는 결과가 발생할 수 있습니다. 통신 시간 제한에 대한 자세한 내용은 COMMTIMEOUTS참조하세요.

단일 섹터 쓰기는 원자성이지만 트랜잭션을 사용하지 않는 한 다중 섹터 쓰기가 원자성으로 보장되지 않습니다(즉, 생성된 핸들은 트랜잭션 핸들입니다. 예를 들어 CreateFileTransacted사용하여 만든 핸들). 캐시된 다중 섹터 쓰기는 항상 디스크에 즉시 기록되지 않을 수 있습니다. 따라서 CreateFileFILE_FLAG_WRITE_THROUGH 지정하여 잠재적인 캐싱 지연 없이 전체 다중 섹터 쓰기가 디스크에 기록되도록 합니다.

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

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

hFileFILE_FLAG_OVERLAPPED사용하여 연 경우 다음 조건이 적용됩니다.

  • lpOverlapped 매개 변수는 유효하고 고유한 OVERLAPPED 구조를 가리킵니다. 그렇지 않으면 함수가 쓰기 작업이 완료되었음을 잘못 보고할 수 있습니다.
  • lpNumberOfBytesWritten 매개 변수는 NULL설정해야 합니다. 기록된 바이트 수를 얻으려면 GetOverlappedResult 함수를 사용합니다. hFile 매개 변수가 I/O 완성 포트와 연결된 경우 GetQueuedCompletionStatus 함수를 호출하여 쓴 바이트 수를 가져올 수도 있습니다.
Windows Server 2012에서 이 함수는 다음 기술에서 지원됩니다.
기술 지원
SMB(서버 메시지 블록) 3.0 프로토콜
SMB 3.0 TFO(투명한 장애 조치(failover)
SO(스케일 아웃 파일 공유)가 있는 SMB 3.0
CsvFS(클러스터 공유 볼륨 파일 시스템)
ReFS(복원 파일 시스템)
 

동기화 및 파일 위치

hFileFILE_FLAG_OVERLAPPED사용하여 열면 비동기 파일 핸들입니다. 그렇지 않으면 동기식입니다. OVERLAPPED 구조를 사용하는 규칙은 앞에서 설명한 대로 각각에 대해 약간 다릅니다.
참고 비동기 I/O에 대해 파일 또는 디바이스를 연 경우 해당 핸들을 사용하는 WriteFile 같은 함수에 대한 후속 호출은 일반적으로 즉시 반환되지만 차단된 실행과 관련하여 동기적으로 동작할 수도 있습니다. 자세한 내용은 Windows비동기 디스크 I/O가 동기로 표시되는 참조하세요.
 
비동기 파일 핸들 작업에 대한 고려 사항:
  • 쓰기 작업이 완료되기 전에 WriteFile 반환할 수 있습니다. 이 시나리오에서 WriteFileFALSE 반환하고 GetLastError 함수는 ERROR_IO_PENDING반환하므로 시스템에서 쓰기 작업을 완료하는 동안 호출 프로세스를 계속할 수 있습니다.
  • lpOverlapped 매개 변수는 NULL 않아야 하며 다음 팩트를 염두에 두어야 합니다.
    • OVERLAPPED 구조에 지정된 이벤트가 시스템에 의해 자동으로 설정되고 다시 설정되지만 OVERLAPPED 구조에 지정된 오프셋은 자동으로 업데이트되지 않습니다.
    • WriteFile I/O 작업을 시작할 때 이벤트를 서명되지 않은 상태로 다시 설정합니다.
    • OVERLAPPED 구조에 지정된 이벤트는 쓰기 작업이 완료되면 신호 상태로 설정됩니다. 이 시간까지 쓰기 작업은 보류 중인 것으로 간주됩니다.
    • 쓰기 작업은 OVERLAPPED 구조에 지정된 오프셋에서 시작되고 WriteFile 시스템 수준 쓰기 작업이 완료되기 전에(쓰기 보류 중) 반환될 수 있으므로 오프셋이나 구조체의 다른 부분은 이벤트가 신호를 받을 때까지 애플리케이션에서 수정, 해제 또는 다시 사용해서는 안 됩니다. 쓰기가 완료됨).
동기 파일 핸들 작업에 대한 고려 사항:
  • lpOverlapped NULL경우 쓰기 작업은 현재 파일 위치에서 시작되고 WriteFile 작업이 완료될 때까지 반환되지 않으며, WriteFile 반환되기 전에 시스템에서 파일 포인터를 업데이트합니다.
  • lpOverlapped NULL않으면 쓰기 작업이 OVERLAPPED 구조에 지정된 오프셋에서 시작되고 쓰기 작업이 완료될 때까지 writeFile 반환되지 않습니다. WriteFile 반환하기 전에 시스템에서 OVERLAPPED 내부 및 InternalHigh 필드 및 파일 포인터를 업데이트합니다.
자세한 내용은 CreateFile동기 및 비동기 I/O참조하세요.

파이프

익명 파이프를 사용하고 읽기 핸들이 닫힌 경우 WriteFile 파이프의 해당 쓰기 핸들을 사용하여 쓰기를 시도하면 함수는 FALSE 반환 하고 getLastError ERROR_BROKEN_PIPE반환합니다.

애플리케이션이 WriteFile 함수를 사용하여 파이프에 쓸 때 파이프 버퍼가 가득 차면 쓰기 작업이 즉시 완료되지 않을 수 있습니다. 읽기 작업(ReadFile 함수 사용)을 통해 파이프에 더 많은 시스템 버퍼 공간을 사용할 수 있게 되면 쓰기 작업이 완료됩니다.

버퍼 공간이 부족한 비차단 바이트 모드 파이프 핸들에 쓸 때 WriteFile *lpNumberOfBytesWritten<nNumberOfBytesToWriteTRUE 반환합니다.

파이프에 대한 자세한 내용은 파이프참조하세요.

트랜잭션 작업

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

예제

몇 가지 예제는 임시 파일 만들기 및 사용 및 읽기 또는 쓰기위해 파일 열기 참조하세요.

다음 C++ 예제에서는 버퍼되지 않은 파일 쓰기에 대한 섹터를 정렬하는 방법을 보여 줍니다. 크기 변수는 파일에 쓰는 데 관심이 있는 원래 데이터 블록의 크기입니다. 버퍼링되지 않은 파일 I/O에 대한 추가 규칙은 파일 버퍼링참조하세요.
#include <windows.h>

#define ROUND_UP_SIZE(Value,Pow2) ((SIZE_T) ((((ULONG)(Value)) + (Pow2) - 1) & (~(((LONG)(Pow2)) - 1))))

#define ROUND_UP_PTR(Ptr,Pow2)  ((void *) ((((ULONG_PTR)(Ptr)) + (Pow2) - 1) & (~(((LONG_PTR)(Pow2)) - 1))))

int main()
{
   // Sample data
   unsigned long bytesPerSector = 65536; // obtained from the GetFreeDiskSpace function.
   unsigned long size = 15536; // Buffer size of your data to write.
   
   // Ensure you have one more sector than Size would require.
   size_t sizeNeeded = bytesPerSector + ROUND_UP_SIZE(size, bytesPerSector);
   
   // Replace this statement with any allocation routine.
   auto buffer = new uint8_t[SizeNeeded];
   
   // Actual alignment happens here.
   auto bufferAligned = ROUND_UP_PTR(buffer, bytesPerSector);

   // ... Add code using bufferAligned here.
   
   // Replace with corresponding free routine.
   delete buffer;
}

요구 사항

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

참고 항목

CancelIo

CancelIoEx

CancelSynchronousIo

CreateFile

createFileTransacted

파일 관리 함수

GetLastError

GetOverlappedResult

GetQueuedCompletionStatus

ReadFile

SetEndOfFile

WriteFileEx