C# 用C语言在几秒钟内创建一个巨大的虚拟文件#
我想在几秒钟内创建一个巨大的虚拟文件,比如说1~2GB。 下面是我用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
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;iSetLength
和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;
}
}
}