【问题标题】:Creating a Huge Dummy File in a Matter of Seconds in C#在 C# 中在几秒钟内创建一个巨大的虚拟文件
【发布时间】:2010-12-25 06:16:03
【问题描述】:

我想在几秒钟内创建一个 1~2 GB 的巨大虚拟文件。 这是我用 C# 写的:

file.writeallbytes("filename",new byte[a huge number]);

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

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();

din 是磁盘信息对象

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

【问题讨论】:

  • BinaryWriter 用于以 .NET 可以读取的格式将 POCO 写入文件,这不是您所期望的名称。

标签: c# file-io


【解决方案1】:

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

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

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

【讨论】:

  • +1 一个有趣的简单解决方案(假设虚拟内容没问题)。
  • 将虚拟文件写入cool/flash/ram磁盘需要相同的时间(我几乎忘记说我正在使用可移动存储)。
  • 内容不可预知:写入时文件将被零填充。如果不这样做,那将是一个安全问题。
  • @RickNZ:虽然这确实适用于普通文件系统,但它不是 API 合同的明确部分,对于某些第三方网络重定向器也不会如此。
  • 仅供参考,这会生成一个大小为 2 GiB + 1 字节的文件
【解决方案2】:

如果您不关心内容,那么到目前为止,我所知道的最快的方法是 - 它几乎是即时的:

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

【讨论】:

  • 出于好奇,测试了SetLengthSeek + WriteByte 方法。使用 Seek 需要 15 秒才能获得 512MB,仅使用 SetLength 需要大约 1 秒。在这两种情况下,即使经过多次测试,文件也充满了 NULL(与任意数据相反)。不确定这是一个干净的磁盘还是一些优化的零填充创建。
  • 好地方 - 非常有趣。我可以在我的身上确认这一点;我冒昧地猜测,在我的情况下它不太可能是一个干净的磁盘(乱七八糟的硬盘!)
  • 对我来说,它比 mdb 的方法需要更长的时间:-?
  • 您是否尝试过多次进行基准测试,每次测试后删除文件,以排除磁盘已满或其他因素的可能影响?
  • 是的,带秒表 :D 所有三种方法(我的 + 你的 + mdbs)它们都在同一个范围内。没有显着差异:-?正如我提到的,我需要将它用于可移动存储,我所有的测试都在可移动存储上。
【解决方案3】:

如果您只需要FileStream,您可以使用FileStream.SetLength。这将为您提供 2 GB 长的流。然后,您可以在您选择的任意位置写入最后一个字节。但是内容是不确定的。

如果您尝试在磁盘上实际创建文件,是的,您需要实际写入其内容。是的,硬盘会变慢。像 1 GB/分钟的写入速度并不是完全荒谬的。抱歉——那是物理学!

【讨论】:

    【解决方案4】:

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

    私有BackgroundWorker bgWorker; 公共表格1() { 初始化组件(); bgWorker = new BackgroundWorker(); bgWorker.DoWork += 新 DoWorkEventHandler(bgWorker_DoWork); bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); bgWorker.RunWorkerAsync(); } void bgWorker_RunWorkerCompleted(对象发送者,RunWorkerCompletedEventArgs e) { this.label2.Text = "完成"; } void bgWorker_ProgressChanged(对象发送者,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(对象发送者,DoWorkEventArgs e) { 长 FSS = din.TotalFreeSpace; 长段 = FSS / 10000; long last_seg = FSS % 10000; BinaryWriter br = new BinaryWriter(fs); for (long i = 0; i

    这是一个草稿...

    【讨论】:

      【解决方案5】:

      我可能是错的,但您可能会发现不可能如此快速地创建一个如此大的文件,因为在 I/O 写入过程中会出现瓶颈。

      但是,在 Applciation.DoEvents 上方的代码中,这会减慢速度。此外,任何重新绘制 screenthis.label2.Text = 都会导致速度稍微变慢。

      【讨论】:

        猜你喜欢
        • 2021-09-08
        • 1970-01-01
        • 2020-08-23
        • 2015-10-06
        • 2015-01-25
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多