다음을 통해 공유


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 매개 변수는 쓰기 액세스 권한으로 만들어졌어야 합니다. 자세한 내용은 일반 액세스 권한파일 보안 및 액세스 권한을 참조하세요.

비동기 쓰기 작업의 경우 hFileFILE_FLAG_OVERLAPPED 플래그 또는 소켓 또는 accept 함수에서 반환된 소켓 핸들을 사용하여 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

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

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

파일 끝에 쓰려면 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의 동작은 SetCommTimeouts 및 GetCommTimeouts 함수를 사용하여 설정된 현재 통신 시간 제한에 따라 결정되고 검색됩니다. 제한 시간 값을 설정하지 못하면 예측할 수 없는 결과가 발생할 수 있습니다. 통신 시간 제한에 대한 자세한 내용은 COMMTIMEOUTS를 참조하세요.

단일 섹터 쓰기는 원자성이지만 트랜잭션을 사용하지 않는 한 다중 섹터 쓰기가 원자성으로 보장되지 않습니다(즉, 생성된 핸들은 트랜잭션 핸들입니다. 예를 들어 CreateFileTransacted를 사용하여 만든 핸들). 캐시된 다중 섹터 쓰기는 항상 디스크에 즉시 기록되지 않을 수 있습니다. 따라서 잠재적인 캐싱 지연 없이 전체 다중 섹터 쓰기가 디스크에 기록되도록 CreateFile에서 FILE_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에서 열린 파일을 성공적으로 사용하기 위한 엄격한 요구 사항이 있습니다. 자세한 내용은 파일 버퍼링을 참조하세요.

FILE_FLAG_OVERLAPPED hFile을 연 경우 다음 조건이 적용됩니다.

  • lpOverlapped 매개 변수는 유효하고 고유한 OVERLAPPED 구조를 가리킵니다. 그렇지 않으면 함수가 쓰기 작업이 완료되었음을 잘못 보고할 수 있습니다.
  • lpNumberOfBytesWritten 매개 변수는 NULL로 설정해야 합니다. 기록된 바이트 수를 얻으려면 GetOverlappedResult 함수를 사용합니다. hFile 매개 변수가 I/O 완성 포트와 연결된 경우 GetQueuedCompletionStatus 함수를 호출하여 작성된 바이트 수를 가져올 수도 있습니다.
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
 

동기화 및 파일 위치

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

파이프

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

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

버퍼 공간이 부족한 비차단 바이트 모드 파이프 핸들에 쓸 때 WriteFile은 *lpNumberOfBytesWritten<nNumberOfBytesToWrite를 사용하여TRUE를 반환합니다.

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

거래된 작업

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

예제

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

다음 C++ 예제에서는 버퍼되지 않은 파일 쓰기에 대한 섹터를 정렬하는 방법을 보여 줍니다. Size 변수는 파일에 쓰는 데 관심이 있는 원래 데이터 블록의 크기입니다. 버퍼링되지 않은 파일 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