2009-12-10 9 views
34

Chcę utworzyć ogromny plik dummy, powiedzmy 1 ~ 2 GB w ciągu kilku sekund. tutaj jest to, co pisałem w C#:Tworzenie ogromnego pliku dummy w masie sekund w C#

file.writeallbytes("filename",new byte[a huge number]); 

i inny sposób ze wskazaniem statusu, był jak następuje:

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(); 

gdzie hałas jest Informacja Disk sprzeciw

dobrze z nich dwa podejścia, aby napisać taki duży, ale fałszywy plik, potrzeba około 2 lub więcej minut. czy jest jakiś inny szybszy sposób na zrobienie tego?

pozdrowienia.

+3

BinaryWriter służy do pisania POCO do pliku w formacie, który może odczytywać .NET, nie jest tym, czego można się spodziewać po nazwie. –

Odpowiedz

67

Wystarczy utworzyć plik, starają się odpowiednio duży offset, i napisać jeden bajt:

FileStream fs = new FileStream(@"c:\tmp\huge_dummy_file", FileMode.CreateNew); 
fs.Seek(2048L * 1024 * 1024, SeekOrigin.Begin); 
fs.WriteByte(0); 
fs.Close(); 

To przyniesie plik 2GB z zasadzie nieprzewidywalnych treści, które powinny być w porządku do swoich celów.

+1

+1 dla intrygująco prostego rozwiązania (zakładając, że obojętne treści są w porządku). – Abel

+0

to zajmie tyle samo czasu, aby napisać plik dummy na dysku cool/flash/ram (prawie zapomnę powiedzieć, że używam pamięci wymiennej). –

+6

Zawartość nie jest nieprzewidywalna: plik zostanie wypełniony zerami podczas zapisywania. Gdyby tego nie zrobiono, byłby to problem bezpieczeństwa. – RickNZ

0

Mogę się mylić, ale prawdopodobnie okaże się, że niemożliwe jest utworzenie pliku, który jest tak szybki, jak będzie wąskie gardło w procesie pisania we/wy.

Jednak w twoim kodzie powyżej Applciation.DoEvents spowalnia rzeczy. Również każde ponowne malowanie numeru screenthis.label2.Text = spowoduje lekkie spowolnienie.

4

Jeśli potrzebujesz tylko FileStream, możesz użyć FileStream.SetLength. Otrzymasz strumień o długości 2 GB. Następnie możesz zapisać końcowy bajt na dowolnie wybranej pozycji. Ale zawartość nie będzie zdefiniowana.

Jeśli próbujesz utworzyć plik na dysku, tak, musisz napisać jego zawartość. I tak, dyski twarde będą wolne; coś w rodzaju prędkości zapisu 1 GB/min nie jest całkowicie śmieszne. Przepraszam - to fizyka!

60

Jeśli nie dbają o zawartość, to zdecydowanie najszybszy sposób znam to jest - to jest praktycznie natychmiastowy:

private void CreateDummyFile(string fileName, long length) 
{ 
    using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) 
    { 
     fileStream.SetLength(length); 
    } 
} 
+0

+1 za wyświetlenie 'używając' i jeszcze bardziej uproszczenie odpowiedzi mdb. – Abel

+9

Z ciekawości, testowane podejścia 'SetLength' i' Seek' + 'WriteByte'. Z * Seek * zajęło 15 sekund dla 512 MB, a tylko * SetLength * zajęło około 1 sekundy. W obu przypadkach, nawet po wielu testach, pliki były wypełnione wartościami NULL (w przeciwieństwie do arbitralnych danych). Nie jestem pewien, czy jest to czysty dysk, czy zoptymalizowany pod kątem zerowym układ pod maską. – Abel

+0

Dobre miejsce - bardzo interesujące. Mogę to potwierdzić na moim; Mogę zaryzykować przypuszczenie, że jest mało prawdopodobne, aby był czystym dyskiem w moim przypadku (brudny i pełny dysk twardy!) –

2

Dlaczego nie użyć klasy BackgroundWorker do osiągnięcia tego celu, ponieważ możesz przekazać cokolwiek do metody ReportProgress, aby wskazać raport o stanie. Patrz poniższy przykład:

 
     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; 
    } 
} 
} 

To brulion ... nadzieję, że to pomaga, poważaniem, Tom.