2017-06-02 70 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

相關問題