web-dev-qa-db-ja.com

Cでfwriteを使用する場合のファイルサイズの2GBの制限?

ディスクに空き容量がなくなるまでファイルに書き込む短いCプログラムがあります。

#include <stdio.h>

int main(void) {
  char c[] = "abcdefghij";
  size_t rez;
  FILE *f = fopen("filldisk.dat", "wb");
  while (1) {
    rez = fwrite(c, 1, sizeof(c), f);
    if (!rez) break;
  }
  fclose(f);
  return 0;
}

(Linuxで)プログラムを実行すると、ファイルが2GBに達すると停止します。

FILE構造などによる内部制限はありますか?

ありがとう。

21
Gabriel

32ビットシステム(つまり、OSが32ビット)では、デフォルトで、fopenとcoは32ビットサイズ/オフセットなどに制限されています...ラージファイルのサポートを有効にするか、* 64ビットオプションを使用する必要があります。

http://www.gnu.org/software/libc/manual/html_node/Opening-Streams.html#index-fopen64-931

次に、fsはこれをサポートする必要がありますが、fatおよびその他のプリミティブfsを除いて、すべてが2GBを超えるファイルの作成をサポートします。

28

ファイルが2GBに達すると停止します。

FILE構造などによる内部制限はありますか?

これは、libc(標準Cライブラリ)によるものです。これは、x86(IA-32)Linuxシステムでは、デフォルトでglibc(GNUのCライブラリ)によって提供される32ビット関数です。したがって、デフォルトでは、 ファイルストリームサイズ は32ビット-2 ^(32-1)に基づいています。

Large File Support の使用については、Webページを参照してください。

#define _FILE_OFFSET_BITS  64
/* or more commonly add -D_FILE_OFFSET_BITS=64 to CFLAGS */

#include <stdio.h>

int main(void) {
  char c[] = "abcdefghij";
  size_t rez;
  FILE *f = fopen("filldisk.dat", "wb");
  while (1) {
    rez = fwrite(c, 1, sizeof(c), f);
    if ( rez < sizeof(c) ) { break; }
  }
  fclose(f);
  return 0;
}

注:ほとんどのシステムは、fopen(およびoff_t)が2 ^ 31のファイルサイズ制限に基づいていることを想定しています。それらをoff64_tおよびfopen64に置き換えると、これが明示的になります。 使用法によっては、最善の方法かもしれません。 ただし、標準ではないため、一般的にはお勧めしません。

12
mctylr