Создание огромного файла-заглушки в секундах в С#
Я хочу создать огромный фиктивный файл, скажем, 1 ~ 2 ГБ в считанные секунды.
вот что я написал на С#:
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 или более минут, чтобы написать такой большой, но фиктивный файл. есть ли другой более быстрый способ для этого?
С уважением.
Ответы
Ответ 1
Просто создайте файл, найдите подходящее большое смещение и напишите один байт:
FileStream fs = new FileStream(@"c:\tmp\huge_dummy_file", FileMode.CreateNew);
fs.Seek(2048L * 1024 * 1024, SeekOrigin.Begin);
fs.WriteByte(0);
fs.Close();
Это даст 2 ГБ файл с в основном непредсказуемым содержимым, что должно быть хорошо для ваших целей.
Ответ 2
Если вы не заботитесь о содержании, то самым быстрым способом, о котором я это знаю, - это практически мгновенно:
private void CreateDummyFile(string fileName, long length)
{
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
fileStream.SetLength(length);
}
}
Ответ 3
Если вам просто нужен FileStream
, вы можете использовать FileStream.SetLength
. Это даст вам поток длиной 2 ГБ. Затем вы можете написать окончательный байт в произвольной позиции по вашему выбору. Но содержимое будет undefined.
Если вы пытаетесь создать файл на диске, да, вам нужно будет написать его содержимое. И да, жесткие диски будут медленными; что-то вроде скорости записи 1 ГБ/мин, не совсем смешно. Извините - эта физика!
Ответ 4
Почему вы не использовали класс 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;
}
}
}
Это черновик...
Ответ 5
Я мог ошибаться, но вы, вероятно, обнаружите, что невозможно создать такой большой файл, поскольку это будет узким местом в процессе записи ввода-вывода.
Однако в вашем коде выше Applciation.DoEvents будет замедлять работу. Также любая перерисовка screenthis.label2.Text = приведет к небольшому замедлению.