Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Huge Dummy File in a Matter of Seconds in C#

Tags:

c#

file-io

I want to create a huge dummy file say 1~2 GBs in matter of seconds. here is what I've written in 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

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?

like image 392
Seyed Vahid Hashemi Avatar asked Dec 10 '09 13:12

Seyed Vahid Hashemi


4 Answers

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.

like image 103
mdb Avatar answered Sep 25 '22 01:09

mdb


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);
    }
}
like image 20
Rob Levine Avatar answered Sep 24 '22 01:09

Rob Levine


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.

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!

like image 20
John Feminella Avatar answered Sep 26 '22 01:09

John Feminella


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:

        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...

like image 35
t0mm13b Avatar answered Sep 26 '22 01:09

t0mm13b