2017-06-02 67 views
5

我需要分配大文件而不调零其内容。我正在制作具有巨大文件大小(数百GB)的步骤fopen => ftruncate => fclose => mmap => (...work...) => munmap。当系统尝试调零文件字节时,应用程序挂起几分钟 - 恕我直言,因为使用了ftruncate在不调零的情况下在磁盘上分配文件

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:

根据@torfoanswer,全部换成我这个几行苹果相关的代码:

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

但只适用于超级用户!

+1

**删除**('ftruncate()'也应该创建一个稀疏文件,所以它似乎只是您的操作系统/文件系统不支持稀疏文件) –

+0

如果您需要制作一个巨大的文件而无需调整其内容,只是'没有做你做的其他事情'而已。如果你的文件系统支持它,那将创建一个稀疏文件。 'fallocate'和其他调用会做相反的事情,它们会预先分配和清零磁盘块。写入稀疏文件时,运行磁盘空间不足的风险,但不会浪费时间对其进行调零。 – Art

+0

@ftruncate'艺术应用通过'Ctrl + C'终止几分钟。 – k06a

回答

5

这是MacOS X,显然。

你可以尝试更换ftruncate呼叫

fcntl(ofd, F_SETSIZE, &size); 

(注意,需要root权限,并可能造成安全漏洞,因为它可能会提供访问,这是以前没有的旧文件内容,所以必须进行处理非常小心。你不关心的“脏文件内容”实际上可能是他一周前删除的用户的银行帐户密码......)

MacOS X并不真正支持稀疏文件 - 它确实创建并维护它们,但其文件系统驱动程序非常希望尽快填补漏洞。

+0

谢谢! 'fcntl(ofd,F_SETSIZE,&result_size);'就像一个魅力! – k06a

+1

@ k06a您*看过我的安全隐患吗? – tofro

+0

是的,我不在乎这个用例的安全问题。这是HDD采矿的地块生成:https://github.com/r-majere/mjminer/pull/3 – k06a

相关问题