C# 用C语言在几秒钟内创建一个巨大的虚拟文件#

C# 用C语言在几秒钟内创建一个巨大的虚拟文件#,c#,file-io,C#,File Io,我想在几秒钟内创建一个巨大的虚拟文件,比如说1~2GB。 下面是我用C写的: 另一种表示状态的方式如下: long FSS = din.TotalFreeSpace; long segments = FSS / 10000; long last_seg = FSS % 10000; BinaryWriter br = new BinaryWriter(fs); for (long i = 0; i < segments; i++) { br.Write(new byte[1000

我想在几秒钟内创建一个巨大的虚拟文件,比如说1~2GB。 下面是我用C写的:

另一种表示状态的方式如下:

long FSS = din.TotalFreeSpace;
long segments = FSS / 10000;
long last_seg = FSS % 10000;
BinaryWriter br = new BinaryWriter(fs);

for (long i = 0; i < segments; i++)
{
    br.Write(new byte[10000]);

    this.label2.Text = "segments write :" + i.ToString() + "\r\n" + "segments remain :" + ((segments-i)+1).ToString();
    Application.DoEvents();
}
br.Write(new byte[last_seg]);
this.label2.Text += "\r\nDone!";
br.Close();
long FSS=din.TotalFreeSpace;
长段=FSS/10000;
长最后一段=FSS%10000;
BinaryWriter br=新的BinaryWriter(fs);
用于(长i=0;i
其中din是磁盘信息对象

使用这两种方法,编写如此大但虚拟的文件需要2分钟或更长的时间。还有其他更快的方法吗


注意。

只需创建文件,寻找适当大的偏移量,然后写入一个字节:

FileStream fs = new FileStream(@"c:\tmp\huge_dummy_file", FileMode.CreateNew);
fs.Seek(2048L * 1024 * 1024, SeekOrigin.Begin);
fs.WriteByte(0);
fs.Close();

这将产生一个2GB的文件,其内容基本上不可预测,这对于您的目的来说应该是好的。

我可能错了,但您可能会发现,创建这么大的文件不可能那么快,因为在I/O写入过程中会出现瓶颈


但是,在上面的代码中,application.DoEvents会减慢速度。另外,对屏幕this.label2.Text=的任何重新绘制都会导致速度稍慢。

如果您只需要
文件流
,可以使用
文件流.SetLength
。这将得到一个2 GB长的流。然后您可以在您选择的任意位置写入最后一个字节。但内容将是未定义的


如果您试图在磁盘上实际创建一个文件,是的,您需要实际写入其内容。是的,硬盘速度会很慢;1 GB/min的写入速度并非完全荒谬。对不起,那是物理

如果你不在乎内容,那么到目前为止,我所知道的最快的方式就是这样——它几乎是即时的:

private void CreateDummyFile(string fileName, long length)
{
    using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
    {
        fileStream.SetLength(length);
    }
}

为什么不使用
BackgroundWorker
类来实现这一点,因为您可以将任何内容传递到方法
ReportProgress
以指示状态报告。请参见下面的示例:

private BackgroundWorker bgWorker; public Form1() { InitializeComponent(); bgWorker = new BackgroundWorker(); bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); bgWorker.RunWorkerAsync(); } void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { this.label2.Text = "Done"; } void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { MyStatus myProgressStatus = (MyStatus)e.UserState; this.label2.Text = string.Format("segments write : {0}" + Environment.Newline + "Segments Remain: {1}", myProgressStatus.iWritten, myProgressStatus.iRemaining); } void bgWorker_DoWork(object sender, DoWorkEventArgs e) { long FSS = din.TotalFreeSpace; long segments = FSS / 10000; long last_seg = FSS % 10000; BinaryWriter br = new BinaryWriter(fs); for (long i = 0; i < segments; i++) { br.Write(new byte[10000]); bgWorker.ReportProgress(i.ToString(), new MyStatus(i, ((segments-i) + 1))); } br.Write(new byte[last_seg]); br.Close(); } public class MyStatus{ public int iWritten; public int iRemaining; public MyStatus(int iWrit, int iRem){ this.iWritten = iWrit; this.iRemaining = iRem; } } } 私人背景工作者; 公共表格1() { 初始化组件(); bgWorker=新的BackgroundWorker(); bgWorker.DoWork+=新的DoWorkEventHandler(bgWorker\u DoWork); bgWorker.ProgressChanged+=新的ProgressChangedEventHandler(bgWorker\u ProgressChanged); bgWorker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(bgWorker\u RunWorkerCompleted); bgWorker.RunWorkerAsync(); } void bgWorker\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e) { this.label2.Text=“完成”; } void bgWorker\u ProgressChanged(对象发送方,ProgressChangedEventArgs e) { MyStatus myProgressStatus=(MyStatus)e.UserState; this.label2.Text=string.Format(“段写入:{0}”+环境。换行符+“段保留:{1}”、myProgressStatus.iWrited、myProgressStatus.iMaining); } void bgWorker\u DoWork(对象发送方,DoWorkEventArgs e) { 长FSS=din总自由空间; 长段=FSS/10000; 长最后一段=FSS%10000; BinaryWriter br=新的BinaryWriter(fs); 用于(长i=0;i这是一个粗略的草稿…

+1,用于一个有趣的简单解决方案(假设虚拟内容是可以的)。将虚拟文件写入cool/flash/ram磁盘需要相同的时间(我几乎忘了说我使用的是可移动存储)。内容不是不可预测的:当您写入时,文件将充满零。如果不这样做,这将是一个安全问题。@RickNZ:虽然对于普通文件系统来说确实如此,但它不是API合同的明确部分,对于某些第三方网络重定向器来说,情况并非如此。仅供参考,这会生成一个大小为2 GiB+1 byteBinaryWriter的文件,用于以.NET可以读取的格式将POCO写入文件,这与您从名称中所期望的不同。出于好奇,测试了
SetLength
Seek
+
WriteByte
方法。使用Seek时,512MB需要15秒,而使用SetLength则需要大约1秒。在这两种情况下,即使经过多次测试,文件中也会填充空值(与任意数据相反)。不确定这是一个干净的磁盘还是一些优化的零填充引擎盖下创建。好点-非常有趣。我可以在我的身上证实这一点;我冒昧地猜测,在我的情况下,它不太可能是一个干净的磁盘(凌乱而完整的硬盘!),对我来说,它需要比mdb的方法更长的时间:-?您是否尝试过多次基准测试,在每次测试后删除文件,以排除磁盘填充或其他因素的可能影响?是的,使用秒表:d所有三种方法(我的+你的+MDB)它们在相同的范围内。没有显著差异:-?正如我提到的,我需要这个用于可移动存储,我所有的测试都是在可移动存储上进行的。 private BackgroundWorker bgWorker; public Form1() { InitializeComponent(); bgWorker = new BackgroundWorker(); bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); bgWorker.RunWorkerAsync(); } void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { this.label2.Text = "Done"; } void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { MyStatus myProgressStatus = (MyStatus)e.UserState; this.label2.Text = string.Format("segments write : {0}" + Environment.Newline + "Segments Remain: {1}", myProgressStatus.iWritten, myProgressStatus.iRemaining); } void bgWorker_DoWork(object sender, DoWorkEventArgs e) { long FSS = din.TotalFreeSpace; long segments = FSS / 10000; long last_seg = FSS % 10000; BinaryWriter br = new BinaryWriter(fs); for (long i = 0; i < segments; i++) { br.Write(new byte[10000]); bgWorker.ReportProgress(i.ToString(), new MyStatus(i, ((segments-i) + 1))); } br.Write(new byte[last_seg]); br.Close(); } public class MyStatus{ public int iWritten; public int iRemaining; public MyStatus(int iWrit, int iRem){ this.iWritten = iWrit; this.iRemaining = iRem; } } }