是否可以使用C#在磁盘上创建一个大的(物理上)连续文件?最好只使用托管代码,但如果不可能,则可以理解非托管解决方案。
答案 0 :(得分:5)
您创建的任何文件都将在逻辑上连续。
如果你想要身体连续,你就是在OS和FS领域。真的(远)超出了普通I / O API的控制范围。
但可能接近的是预先声明空间:创建一个空流并将长度或位置属性设置为您需要的。
答案 1 :(得分:3)
写一个defragger?
听起来你还是在碎片整理API之后: -
http://msdn.microsoft.com/en-us/library/aa363911%28v=vs.85%29.aspx
来自底部的链接,因为您似乎错过了某人亲切制作的C#包装器。
http://blogs.msdn.com/b/jeffrey_wall/archive/2004/09/13/229137.aspx
答案 2 :(得分: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();
答案 3 :(得分:1)
要构建数据库,您需要使用Windows API提供的分散 - 聚集I / O功能。这是一种特殊类型的文件I / O,允许您将文件中的数据“分散”到内存中或从内存中“收集”数据并将其写入文件的连续区域。虽然分散数据或从中收集数据的缓冲区不需要是连续的,但源文件区域或目标文件区域始终是连续的。
此功能由两个主要功能组成,两个主要功能都是异步工作的。 ReadFileScatter
function从磁盘上的文件读取连续数据,并将其写入非连续内存缓冲区数组。 WriteFileGather
function从内存缓冲区中读取非连续数据,并将其写入磁盘上的连续文件。当然,您还需要这两个函数使用的OVERLAPPED
structure。
这正是SQL Server在读取和写入数据库和/或其日志文件时使用的内容,实际上此功能已添加到NT 4.0的早期Service Pack中,专门用于SQL Server。
当然,这是非常高级的东西,而且对于胆小的人来说也是如此。令人惊讶的是,您实际上可以在pinvoke.net上找到P / Invoke定义,但我对该网站存在强烈的怀疑。由于您需要花费大量时间阅读文档以了解这些函数的工作原理,因此您也可以自己编写声明。从C#中执行此操作将为您创建一系列其他问题,因此我甚至不推荐它。如果这种I / O性能对您很重要,我认为您使用的是错误的工具。
穷人的解决方案是 contig.exe ,一个可以免费下载here的单文件碎片整理程序。
答案 4 :(得分:0)
总之没有
操作系统将在后台执行此操作,我要做的是使文件尽可能大,这样操作系统就会将其重新放置。如果你需要增长文件,你每次再增加10%。 这与SQL服务器如何保存数据库文件类似。
打开FileStream打开它,并附加。
示例:
FileStream fwriter = new FileStream("C:\\test.txt", FileMode.Append, FileAccess.Write, FileShare.Read);