쓰기가 버퍼에 4K 바이트를 계속 남기는 이유는 무엇입니까?


30

본질적으로 다음 코드가 있습니다.

int fileWrite(int file, void * pBuffer, size_t size)
{
    size_t bytesWritten = (size_t)write( file, pBuffer, size ) ;
    if (bytesWritten != size)
    {
       return -1;
    }
    return 0;
}

크기가 1GB이면 작동하지만 크기가 ~ 2GB이면 4K 바이트가 일관되게 남아 있습니다. 루프에서 쓰기를 래핑하고 버퍼를 위로 이동 하여이 문제를 해결할 수 있지만 왜 항상 실패하는지 궁금합니다.

예를 들어 size가 2147483648 인 경우 쓰기는 2147479552 만 작성하고 4096은 쓰지 않습니다. 왜 이런 일이 발생하고 항상 루프에서 쓰기를 래핑하는 것이 맞습니까?


2
32 비트 모드로 실행 중입니까? 2gig는 최대 32 비트 숫자입니다.
Barmar

2
write한 번에 소비되는 데이터 양에 대한 규칙은 file"일반"파일, 파이프, 스트림 소켓, 데이터 그램 소켓 등 의 데이터 싱크 유형에 따라 다릅니다 . 더 자세하게 얘기해 주 시겠어요?
zwol

7
잠깐, write한 번에 전체 파일 을 보려고 합니까? 일반적인 접근 방식은 모든 것을 쓸 때까지 한 번에 버퍼 크기로 데이터를 스트리밍하는 것입니다.
루안

4
@Luaan 이미 모든 데이터를 가지고 있다면 한 번에 잘못 쓰는 것이 없다는 것을 알지 못하지만이 질문과 답변에서 알 수 있듯이 write()모든 것을 쓸 필요는 없습니다 (작은 버퍼에도 적용됨)
파이프

8
"루프에 쓰기를 래핑하여이 문제를 해결할 수 있습니다." SSIZE_MAX제한에 관계없이해야합니다 . write()사양은 거의 항상 않는 경우에도 전체 버퍼를 작성하는 의무를 말한다. 문제의 루프리스 코드는 버그입니다.
아담

답변:


50

당신은 대답을 찾을 수 있습니다 man 2 write:

이 수가 요청 된 바이트 수보다 작은 경우 오류가 아닙니다. 예를 들어 디스크 장치가 가득 차서 발생할 수 있습니다.


그리고 write()매뉴얼 페이지 설명에서 :

ssize_t write(int fd, const void *buf, size_t count);

POSIX.1에 따르면, count보다 크면 SSIZE_MAX결과는 구현 정의됩니다. Linux 상한에 대한 참고 사항을 참조하십시오.

노트

Linux에서 write()(및 유사한 시스템 호출) 최대 0x7ffff000(2,147,479,552) 바이트를 전송하여 실제로 전송 된 바이트 수를 반환합니다. 이것은 32 비트 및 64 비트 시스템 모두에 해당됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.