書き込みが連続して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一度に消費するデータ量のルールは、データシンクのタイプfile(「通常の」ファイル、パイプ、ストリームソケット、データグラムソケットなど)によって異なります。より具体的にできますか?
zwol

7
待って、あなたwriteはすぐにファイル全体を試していますか?通常のアプローチは、すべてを書き込むまで、一度にバッファサイズのデータ​​をストリーミングすることです。
ルアン

4
@Luaanあなたはすでに私はそこのこと何も表示されていないすべてのデータがある場合は間違っをすべてこの質問と回答を示したら、しかしとしてでそれを書くことを、write()(小さすぎるバッファのために行くもの)それをすべてを記述する必要はありません
パイプ

8
「書き込みをループでラップすることでこれを修正できます」というSSIZE_MAX制限に関係なく、修正する必要があります。write()仕様では、それはそれはほとんど常にしていても、完全なバッファを書き込むための義務を負いませんと言います。問題のループのないコードはバグです。
アダム

回答:


50

あなたは答えを見つけることができますman 2 write

この数が要求されたバイト数より小さい場合はエラーではありません。これは、たとえば、ディスクデバイスがいっぱいになったために発生する可能性があります。


そしてwrite()manページの説明から:

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.