Yazma neden arabellekte sürekli 4K bayt bırakıyor?


30

Temelde aşağıdaki kod var:

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

Boyut 1GB ise çalışır, ancak boyut ~ 2GB olduğunda, 4K bayt sürekli olarak kalır. Bunu bir döngüde yazma ve arabelleği yukarı taşıyarak düzeltebilirim, ancak neden her zaman başarısız olduğunu merak ediyorum.

Örneğin, boyut 2147483648 ise, yazma yalnızca 2147479552 yazar ve 4096 yazılmadan kalır. Bu neden olur ve yazma işlemini her zaman bir döngüde sarmak doğru olur?


2
32 bit modunda mı çalıştırıyorsunuz? 2gig maksimum 32-bit sayıdır.
Barmar

2
Bir writekerede ne kadar veri tüketileceğine ilişkin kurallar , ne tür bir veri havuzunun olduğuna bağlıdır file(örn. "Normal" dosya, boru, akış soketi, datagram soketi, ...). Daha spesifik olabilir misiniz?
zwol

7
Bekle, writetüm dosyayı bir kerede mi deniyorsun ? Her zamanki yaklaşım, siz her şeyi yazana kadar her seferinde arabellek boyutunda veri akışıdır.
Luaan

4
@Luaan Zaten tüm verilere sahipseniz, hepsini bir kerede yazmakta yanlış bir şey olduğunu görmüyorum, ancak bu soru ve cevabın gösterdiği gibi, write()hepsini yazmak zorunda değil (küçük tamponlar için de geçerli)
boru

8
"Bunu bir döngüde yazma yaparak düzeltebilirim" ve SSIZE_MAXkısıtlamadan bağımsız olarak bunu yapmanız gerekir . write()Spec o neredeyse her zaman yapar bile, tam tampon yazmak için yükümlülüğü yoktur diyor. Söz konusu döngü içermeyen kod bir hatadır.
Adam

Yanıtlar:


50

Cevabı şu adreste bulabilirsiniz man 2 write:

Bu sayının istenen bayt sayısından küçük olması bir hata değildir; bu, örneğin disk aygıtı doldurulmuş olduğu için olabilir.


Ve write()adam sayfası açıklamasından:

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

POSIX.1'e göre, eğer countdaha büyükse SSIZE_MAX, sonuç uygulama tanımlıdır; Linux'ta üst sınır için NOTLAR'a bakın.

NOTLAR

Linux'ta write()(ve benzer sistem çağrıları) en çok 0x7ffff000(2.147.479.552) bayt aktarır ve gerçekte aktarılan bayt sayısını döndürür. (Bu hem 32 bit hem de 64 bit sistemler için geçerlidir.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.