Подтвердить что ты не робот

Создание огромного файла-заглушки в секундах в С#

Я хочу создать огромный фиктивный файл, скажем, 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 или более минут, чтобы написать такой большой, но фиктивный файл. есть ли другой более быстрый способ для этого?

С уважением.

4b9b3361

Ответ 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 = приведет к небольшому замедлению.