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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1881050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:36:35  来源:igfitidea点击:

Creating a Huge Dummy File in a Matter of Seconds in C#

c#file-io

提问by Seyed Vahid Hashemi

I want to create a huge dummy file say 1~2 GBs in matter of seconds. here is what I've written in C# :

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

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

and another way with indicating the status, was like following :

以及指示状态的另一种方式,如下所示:

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

where din is Disk Information object

其中 din 是磁盘信息对象

well with these two approach it takes something like 2 or more minutes to write such a big but dummy file. is there any other faster way for doing so?

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

regards.

问候。

采纳答案by mdb

Simply create the file, seek to a suitably large offset, and write a single byte:

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

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

This will yield a 2GB file with basically unpredictable contents, which should be fine for your purposes.

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

回答by Kane

I could be wrong but you will probably find that it's impossible to create a file that large that quickly as there will be a bottleneck in the I/O writing process.

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

However in your code above the Applciation.DoEvents will be slowing things down. Also any repainting of the screenthis.label2.Text =will cause a slight slow down.

但是,在您上面的代码中, Applciation.DoEvents 会减慢速度。此外,对screenthis.label2.Text = 的任何重绘都会导致速度稍慢。

回答by John Feminella

If you just need a FileStream, you could use FileStream.SetLength. That will get you a stream which is 2 GB long. Then you can write the final byte at an arbitrary position of your choice. But the contents will be undefined.

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

If you're trying to actually create a file on the disk, yes, you'll need to actually write its contents. And yes, hard disks are going to be slow; something like a 1 GB/min write speed isn't totally ridiculous. Sorry -- that's physics!

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

回答by Rob Levine

If you don't care about the contents, then by far the fastest way I know of is this - it is practically instant:

如果你不关心内容,那么到目前为止我所知道的最快的方法是这个 - 它实际上是即时的:

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

回答by t0mm13b

Why did you not use the BackgroundWorkerclass to achieve this, as you can pass anything into the method ReportProgressto indicate the status report. See the example below:

为什么不使用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;
   }
}
}

This is a rough draft...

这是一个草稿...