2011-02-02 84 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