Создание огромного фиктивного файла за считанные секунды в C#
Я хочу создать огромный фиктивный файл, скажем, 1~2 ГБ за считанные секунды. вот что я написал в 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 или больше минуты, чтобы написать такой большой, но фиктивный файл. Есть ли другой быстрый способ сделать это?
С уважением.
5 ответов
Просто создайте файл, найдите подходящее большое смещение и запишите один байт:
FileStream fs = new FileStream(@"c:\tmp\huge_dummy_file", FileMode.CreateNew);
fs.Seek(2048L * 1024 * 1024, SeekOrigin.Begin);
fs.WriteByte(0);
fs.Close();
Это даст файл 2 ГБ с непредсказуемым содержимым, что вполне подойдет для ваших целей.
Если вас не волнует содержание, то самый быстрый способ, который я знаю, - это практически мгновенно:
private void CreateDummyFile(string fileName, long length)
{
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
fileStream.SetLength(length);
}
}
Если вам просто нужно FileStream
Вы могли бы использовать FileStream.SetLength
, Это даст вам поток длиной 2 ГБ. Затем вы можете написать последний байт в произвольной позиции по вашему выбору. Но содержание будет неопределенным.
Если вы на самом деле пытаетесь создать файл на диске, да, вам действительно нужно записать его содержимое. И да, жесткие диски будут медленными; что-то вроде скорости записи 1 ГБ / мин не совсем смешно. Извините - это физика!
Почему вы не использовали BackgroundWorker
класс для достижения этого, так как вы можете передать что-нибудь в метод ReportProgress
указать отчет о состоянии. Смотрите пример ниже:
частный BackgroundWorker bgWorker; public Form1() { InitializeComponent(); bgWorker = new BackgroundWorker(); bgWorker.DoWork += новый DoWorkEventHandler(bgWorker_DoWork); bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); bgWorker.RunWorkerCompleted += новый RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); bgWorker.RunWorkerAsync(); } void bgWorker_RunWorkerCompleted(отправитель объекта, RunWorkerCompletedEventArgs e) { this.label2.Text = "Done"; } void bgWorker_ProgressChanged(отправитель объекта, ProgressChangedEventArgs e) { MyStatus myProgressStatus = (MyStatus)e.UserState; this.label2.Text = string.Format("сегменты пишут: {0}" + Environment.Newline + "Сегменты остаются: {1}", myProgressStatus.iWritten, myProgressStatus.iRemaining); } void bgWorker_DoWork(отправитель объекта, DoWorkEventArgs e) { long FSS = din.TotalFreeSpace; длинные сегменты = FSS / 10000; long last_seg = FSS % 10000; BinaryWriter br = новый BinaryWriter(фс); for (long i = 0; i<сегменты; i ++) {br.Write (новый байт [10000]); bgWorker.ReportProgress (i.ToString (), новый MyStatus (i, ((сегменты-i) + 1))); } br.Write (новый байт [last_seg]); br.Close (); } открытый класс MyStatus {public int iWritten; public int iRemaining; public MyStatus (int iWrit, int iRem) {this.iWritten = iWrit; this.iRemaining = iRem; }}}
Это черновик... Надеюсь, это поможет, С наилучшими пожеланиями, Том.
Я могу ошибаться, но вы, вероятно, обнаружите, что невозможно создать такой большой файл так быстро, поскольку в процессе записи ввода / вывода возникнет узкое место.
Однако в вашем коде выше Applciation.DoEvents будет замедлять процесс. Также любая перекраска screenthis.label2.Text = приведет к небольшому замедлению.