巨大なファイルをゼロにする必要があります。私はこのステップを巨大なファイルサイズ(何百ギガバイトもの)を伴うfopen => ftruncate => fclose => mmap => (...work...) => munmap
を作り出しています。システムがファイルバイトをゼロにしようとしている間、アプリケーションは終了時に数分間停止します - ftruncate
のためIMHO。ゼロ化せずにディスクにファイルを割り当てます。
ftruncate(ofd, 0);
#ifdef HAVE_FALLOCATE
int ret = fallocate(ofd, 0, 0, cache_size);
if (ret == -1) {
printf("Failed to expand file to size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
#elif defined(HAVE_POSIX_FALLOCATE)
int ret = posix_fallocate(ofd, 0, cache_size);
if (ret == -1) {
printf("Failed to expand file to size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
#elif defined(__APPLE__)
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, cache_size, 0};
int ret = fcntl(ofd, F_PREALLOCATE, &store);
if (ret == -1) {
store.fst_flags = F_ALLOCATEALL;
ret = fcntl(ofd, F_PREALLOCATE, &store);
}
if (ret == -1) { // read fcntl docs - must test against -1
printf("Failed to expand file to size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
struct stat sb;
ret = fstat(ofd, &sb);
if (ret != 0) {
printf("Failed to write to file to establish the size.\n");
exit(-1);
}
//ftruncate(ofd, cache_size); <-- [1]
#endif
コメント行[1]
とは動作しないようです。しかし、この行のコメントを外して、私が避けようとしているファイルのゼロ調整を生成します。私は本当に書く前に汚いファイルの内容を気にしません。私はアプリの終了時にハングアップしないようにしたい。
SOLUTION:
@torfoさんanswerによると、この数行ですべての私のApple関連のコードを置き換える:
unsigned long long result_size = cache_size;
int ret = fcntl(ofd, F_SETSIZE, &result_size);
if(ret == -1) {
printf("Failed set size %llu (errno %d - %s).\n", cache_size, errno, strerror(errno));
exit(-1);
}
しかし、唯一のスーパーユーザのために働きます!
** **( 'ftruncate()'もスパースファイルを作成する必要がありますので、あなたのOS /ファイルシステムはスパースファイルをサポートしていないようです) –
コンテンツをゼロにしないで巨大なファイルを作成する必要がある場合あなたがする他のことをすることなく 'ftruncate'するだけです。あなたのファイルシステムがそれをサポートしている場合、それはスパースファイルを作成します。 'fallocate'と他の呼び出しは逆を行い、ディスクブロックをあらかじめ割り当ててゼロにします。スパースファイルに書き込むときにディスク領域が不足する危険性がありますが、時間を無駄にすることはありません。 – Art
'Ctrl + C 'で終了すると' ftruncate'の@Artアプリが数分間停止します。 – k06a