ทำไมการเขียนทิ้งไบต์ 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 ไบต์อย่างสม่ำเสมอ ฉันสามารถแก้ไขได้โดยการเขียนการวนซ้ำและย้ายบัฟเฟอร์ขึ้น แต่ฉันอยากรู้ว่าทำไมมันล้มเหลวอยู่เสมอ

ตัวอย่างเช่นถ้าขนาดคือ 2147483648 เขียนเฉพาะเขียน 2147479552 ปล่อย 4096 ไม่ได้เขียน ทำไมสิ่งนี้ถึงเกิดขึ้นและถูกต้องหรือไม่ที่จะเขียนการวนซ้ำ


2
คุณใช้งานในโหมด 32 บิตหรือไม่? 2gig เป็นจำนวนสูงสุด 32 บิต
Barmar

2
กฎสำหรับปริมาณข้อมูลที่writeจะใช้ในครั้งเดียวขึ้นอยู่กับประเภทของ data sink file(เช่นไฟล์ "ปกติ", ไพพ์, สตรีมซ็อกเก็ต, ซ็อกเก็ตดาตาแกรม, ... ) คุณจะเจาะจงมากขึ้นได้ไหม?
zwol

7
เดี๋ยวก่อนคุณพยายามwriteไฟล์ทั้งหมดในครั้งเดียวหรือไม่? วิธีการปกติคือการสตรีมข้อมูลขนาดบัฟเฟอร์ในแต่ละครั้งจนกว่าคุณจะเขียนทุกอย่าง
Luaan

4
@ Luaan หากคุณมีข้อมูลทั้งหมดอยู่แล้วฉันไม่เห็นว่ามีอะไรผิดพลาดในการเขียนทั้งหมดในครั้งเดียว แต่เนื่องจากคำถามและคำตอบนี้แสดงให้เห็นว่าwrite()ไม่ต้องเขียนทั้งหมด (ซึ่งไปสำหรับบัฟเฟอร์ขนาดเล็กเกินไป)
pipe

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.