在几秒钟内用 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
Creating a Huge Dummy File in a Matter of Seconds in C#
提问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 BackgroundWorker
class to achieve this, as you can pass anything into the method ReportProgress
to 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...
这是一个草稿...