2011-02-02 79 views
3

是否有可能使用C#在磁盤上創建大型(物理上)連續的文件?最好只使用託管代碼,但如果它不可能,那麼將理解非託管解決方案。使用C#創建連續文件?

+2

爲什麼你覺得你需要一個*物理*連續的文件?你想解決什麼問題? – 2011-02-02 11:36:46

+0

我正在建立一種nosql數據庫和磁盤IO性能是一個優先事項。數據庫解決方案(如mysql,sqlserver)總是使用連續的文件來提升性能。 – tmitchel2 2011-02-02 11:47:29

回答

0

總之沒有那麼

操作系統會在後臺做到這一點,我會做的是使你希望它是文件大,這樣操作系統將contigously放置。如果你需要增長文件,你每次增長10%。 這與SQL服務器如何保存數據庫文件相似。

打開打開你追加打開它的FileStream。

例子:

FileStream fwriter = new FileStream("C:\\test.txt", FileMode.Append,  FileAccess.Write, FileShare.Read); 
+0

這將確保在硬盤上,文件將被連續寫入?我想不是。 – Oded 2011-02-02 11:28:58

+0

sry,你的權利。更新回覆 – EKS 2011-02-02 11:29:50

5

您創建的任何文件將在邏輯上是連續的。

如果你想連續的物理你是在OS和FS領土。真正(遠)超出正常I/O API的控制。

但是可能會接近是要求空間的前期:創建一個空流和長度或位置屬性設置爲你所需要的。

2

隨着現代文件系統就很難保證硬盤上的連續文件。從邏輯上說,文件始終是連續的,但保留數據的物理塊因文件系統而異。

這樣做的最好的辦法是使用舊的文件系統(ext2的,FAT32等),只要求使用尋找到你想要的文件的大小,然後刷新該文件的大型文件。更新的文件系統可能會標記大文件大小,但實際上不會將任何內容寫入硬盤,而是在將來讀取時返回零而不實際讀取。

int fileSize = 1024 * 1024 * 512; 
FileStream file = new FileStream("C:\\MyFile", FileMode.Create, FileAccess.Write); 
file.Seek(fileSize, SeekOrigin.Begin); 
file.Close(); 
1

要建立一個數據庫,則需要使用分散收集我的Windows API提供/ O功能。這是一種特殊類型的文件I/O,它允許您將文件中的數據「分散」到內存中或從內存「收集」數據並將其寫入文件的連續區域。儘管數據分散到其中或從中收集數據的緩衝區不必是連續的,但源或目標文件區域始終是連續的。

該功能包括兩個主要功能,這兩者的異步工作。 ReadFileScatter function從磁盤上的文件讀取連續的數據並將其寫入非連續內存緩衝區的數組中。 WriteFileGather function從內存緩衝區讀取非連續數據並將其寫入磁盤上的連續文件。當然,您還需要這兩個函數都使用的OVERLAPPED structure

這正是SQL Server在讀取和寫入數據庫和/或其日誌文件時使用的內容,事實上,此功能已添加到專門用於SQL Server的NT 4.0早期Service Pack中。

當然,這是相當先進的水平的東西,幾乎沒有心臟。令人驚訝的是,您實際上可以在pinvoke.net上找到P/Invoke定義,但我對該網站有着強烈的懷疑不信任。既然你需要在文檔上花費大量的時間來理解這些函數是如何工作的,那麼你也可以自己編寫聲明。而從C#開始將會爲您創建一系列其他問題,因此我甚至不會推薦它。如果這種I/O性能對您很重要,我認爲您使用的是錯誤的工具。

窮人的解決方案是contig.exe,一個單文件碎片整理程序可免費下載here