Tại sao ghi liên tục để lại byte 4K trong bộ đệm?


30

Tôi về cơ bản có mã sau đây:

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;
}

Nó hoạt động nếu kích thước là 1GB, nhưng khi kích thước ~ 2GB, nó sẽ nhận được 4K byte một cách nhất quán. Tôi có thể khắc phục điều này bằng cách gói ghi trong một vòng lặp và di chuyển bộ đệm lên nhưng tôi tò mò về lý do tại sao nó luôn bị lỗi.

Ví dụ: nếu kích thước là 2147483648, hãy viết chỉ ghi 2147479552, để lại 4096 không ghi tên. Tại sao điều này sẽ xảy ra và nó có đúng không khi luôn luôn viết ghi trong một vòng lặp?


2
Bạn đang chạy nó ở chế độ 32 bit? 2gig là số lượng tối đa 32 bit.
Barmar

2
Các quy tắc về lượng dữ liệu writesẽ tiêu thụ cùng một lúc tùy thuộc vào loại dữ liệu chìm file(ví dụ: tệp "thông thường", đường ống, ổ cắm luồng, ổ cắm datagram, ...). Bạn có thể cụ thể hơn không?
zwol

7
Đợi đã, bạn đang cố gắng để writetoàn bộ tập tin cùng một lúc? Cách tiếp cận thông thường là truyền dữ liệu theo kích thước bộ đệm tại một thời điểm cho đến khi bạn viết mọi thứ.
Luaan

4
@Luaan Nếu bạn đã có tất cả dữ liệu tôi không thấy có gì sai khi viết tất cả cùng một lúc nhưng vì câu hỏi và câu trả lời này minh họa, write()không phải viết tất cả (cũng dành cho bộ đệm nhỏ)
ống

8
"Tôi có thể khắc phục điều này bằng cách gói ghi trong một vòng lặp" và bạn cần, bất kể SSIZE_MAXhạn chế. Thông write()số kỹ thuật nói rằng không có nghĩa vụ phải viết bộ đệm đầy đủ, ngay cả khi nó hầu như luôn luôn như vậy. Mã không có vòng lặp trong câu hỏi là một lỗi.
Adam

Câu trả lời:


50

Bạn có thể tìm thấy câu trả lời trong man 2 write:

Không có lỗi nếu số này nhỏ hơn số byte được yêu cầu; điều này có thể xảy ra ví dụ vì thiết bị đĩa đã được lấp đầy.


Và từ write()mô tả trang người đàn ông:

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

Theo POSIX.1, nếu countlớn hơn SSIZE_MAX, kết quả được xác định theo thực hiện; xem GHI CHÚ cho giới hạn trên của Linux.

GHI CHÚ

Trên Linux, write()(và các cuộc gọi hệ thống tương tự) sẽ chuyển tối đa 0x7ffff000(2.147.479.552) byte, trả về số byte thực sự được chuyển. (Điều này đúng trên cả hệ thống 32 bit và 64 bit.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.