2009-01-18 85 views
15

我需要創建一個相對較大(1-8 GB)的文件。在使用C或C++的Windows上這樣做最快的方法是什麼?我需要在飛行中創建它們,速度確實是一個問題。文件將用於存儲仿真,即將以不同的偏移量隨機訪問,並且我需要所有存儲都將預分配但未初始化,目前我們正在使用虛擬數據寫入所有存儲並且時間太長。在Windows上創建大文件

謝謝。

回答

26

使用Win32 API,CreateFile,SetFilePointerEx,SetEndOfFileCloseHandle。以同樣的順序。

訣竅在SetFilePointerEx函數中。從MSDN:

請注意,這是不是一個錯誤設置 文件指針的位置超越 文件的末尾。在調用 SetEndOfFile,WriteFile或WriteFileEx函數之前, 文件的大小不會增加。

將資源從一個位置複製到另一個位置時,Windows資源管理器實際上也執行同樣的操作。它這樣做是爲了使磁盤不需要爲分片磁盤重新分配文件。

+0

經過測試,它如期工作,感謝Brian。 – Ilya 2009-01-18 16:26:20

+0

這將只在NTFS和exFAT上運行,而不是在FAT32,FAT16上。 這是因爲這些文件系統有一個「初始化大小」 – 2010-08-25 18:30:35

+0

「SetEndOfFile()」在寫入文件時會導致嚴重的延遲。如果您將文件寫入文件的中間,則Windows將會將所有尚未寫入的塊清零,直至寫入的位置。參見http://blogs.msdn.com/b/oldnewthing/archive/2011/09/22/10215053.aspx(我可以親自證實這一點,在編寫IO基準測試應用程序時我親眼目睹了這種效果。) – 2014-02-14 14:23:30

2

結賬memory mapped files

它們非常符合您描述的用例,高性能和隨機訪問。

我相信他們不需要被創建爲大文件。你只需在它們上面設置一個很大的最大尺寸,當你寫下你以前沒有碰過的零件時它們就會被擴大。

0

如果您使用NTFS然後sparse files是要走的路:

其中許多數據是 零的文件據說含有稀疏數據 集。像這些文件通常是非常大的 - 例如,文件 包含要處理的圖像數據 或高速數據庫內的矩陣。包含稀疏數據集的文件 的問題是 大部分文件不包含 包含有用的數據,並且由於 這樣,它們的磁盤空間使用效率低下 。

NTFS文件 系統中的文件壓縮是 問題的部分解決方案。文件中未明確寫入的所有數據 明確爲 設爲零。文件壓縮契約 這些範圍爲零。但是,文件壓縮的​​缺點在於 訪問時間可能由於數據 壓縮和解壓縮而增加。

支持稀疏文件介紹 在NTFS文件系統中的另一種方式 使磁盤空間的使用更加高效 。當啓用稀疏文件 功能時,系統 不會爲文件分配硬盤空間至 文件,但 包含非零數據的區域除外。當嘗試寫入 操作,其中緩衝區中的大量數據量爲 零時,零不會寫入 文件。相反,文件系統 創建了一個包含 文件中零的位置的內部列表,並且在所有讀取操作期間向該列表查詢 。當所在的地區零均位於該文件的 執行 讀操作, 文件系統返回分配給讀 操作 緩衝零的 適當數量。通過這種方式,稀疏文件的維護對於訪問它的所有 進程都是透明的,並且對於此特定場景的壓縮效率更高,爲 。

0

使用 「FSUTIL」 命令:

E:\ VirtualMachines> FSUTIL文件createnew 用法:FSUTIL文件createnew 例如:FSUTIL文件createnew C:\ TESTFILE.TXT 1000

Reagds

PS它是Windows 2000/XP/7

1

this的解決方案是不壞,但你正在尋找的東西是SetFileValidData

由於MSDN賽斯:

的SetFileValidData功能允許您避免在向文件不連續寫入時用 填充數據。

因此,這總是將磁盤數據保留原樣,SetFilePointerEx應將所有數據設置爲零,因此大的分配需要一些時間。

0

我知道你的問題是用Windows標記的,Brian R. Bondy給了你最好的答案,如果你確實知道你不需要將你的應用程序移植到其他平臺。但是,如果您可能需要將您的應用程序移植到其他平臺上,那麼您可能需要做一些更像Adrian Cornish提出的問題,作爲「如何創建」x「大小的文件」的答案?發現在How to create file of "x" size?

FILE *fp=fopen("myfile", "w"); 
fseek(fp, 1024*1024, SEEK_SET); 
fputc('\n', fp); 
fclose(fp); 

當然,還有一個轉折點。 Adrian Cornish提出的答案使用了具有以下簽名的fseek函數。

int fseek (FILE * stream, long int offset, int origin); 

問題是您要創建一個文件大小超出32位整數範圍的非常大的文件。您需要使用fseek的64位等價物。不幸的是,在不同的平臺上它有不同的名字。

http://mosaik-aligner.googlecode.com/svn-history/r2/trunk/src/CommonSource/Utilities/LargeFileSupport.h找到的頭文件LargeFileSupport.h提供瞭解決這個問題的方法。

這將允許你寫下面的函數。

#include "LargeFileSupport.h" 
/* Include other headers. */ 

bool createLargeFile(const char * filename, off_type size) 
{ 
    FILE *fp = fopen(filename, "w"); 
    if (!fp) 
    { 
     return false; 
    } 
    fseek64(fp, size, SEEK_SET); 
    fputc('\n', fp); 
    fclose(fp); 
} 

我想我會添加這個以防萬一信息對您有用。