2009-12-10 7 views
34

Voglio creare un enorme file fittizio diciamo 1 ~ 2 GB in pochi secondi. qui è quello che ho scritto in C#:Creazione di un file fittizio enorme in una questione di secondi in C#

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

e un altro modo, con l'indicazione dello stato, era come segue:

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

dove din è Disk Information oggetto

bene con questi due approcci ci vogliono qualcosa come 2 o più minuti per scrivere un file così grande ma fittizio. c'è qualche altro modo più veloce per farlo?

saluti.

+3

BinaryWriter è per la scrittura di POCO in un file in un formato di cui .NET può leggere, non è quello che ci si aspetterebbe dal nome. –

risposta

67

sufficiente creare il file, cercano di un opportunamente grande offset, e scrivere un singolo byte:

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

Ciò produrrà un file di 2 GB con contenuti sostanzialmente imprevedibili, che dovrebbe andare bene per i vostri scopi.

+1

+1 per una soluzione intrigante semplice (presupponendo che il contenuto fittizio sia ok). – Abel

+0

ci vorrà lo stesso tempo per scrivere il file fittizio nel disco cool/flash/ram (mi dimentico quasi di dire che sto usando la memoria rimovibile). –

+6

I contenuti non sono imprevedibili: il file verrà riempito di zeri quando si scrive. Se ciò non fosse fatto, sarebbe un problema di sicurezza. – RickNZ

0

Potrei sbagliarmi ma probabilmente scoprirete che è impossibile creare un file così grande tanto rapidamente quanto vi sarà un collo di bottiglia nel processo di scrittura I/O.

Tuttavia nel codice sopra l'Applciation.DoEvents rallenterà le cose. Inoltre, qualsiasi riverniciatura dello screenthis.label2.Text = causerà un leggero rallentamento.

4

Se è sufficiente uno FileStream, è possibile utilizzare FileStream.SetLength. Ciò ti procurerà un flusso lungo 2 GB. Quindi puoi scrivere il byte finale in una posizione arbitraria di tua scelta. Ma i contenuti saranno indefiniti.

Se si sta tentando di creare effettivamente un file sul disco, sì, è necessario scrivere effettivamente il suo contenuto. E sì, gli hard disk saranno lenti; qualcosa come una velocità di scrittura di 1 GB/min non è totalmente ridicolo. Scusa, questa è fisica!

60

Se non si preoccupano i contenuti, quindi di gran lunga il modo più veloce che conosco è questo - è praticamente immediato:

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

+1 per mostrare 'using' e rendere la risposta di mdb ancora più semplice. – Abel

+9

Per curiosità, approcci testati 'SetLength' e' Seek' + 'WriteByte'. Con * Seek * ci sono voluti 15 secondi per 512 MB, con solo * SetLength * ci sono voluti circa 1 secondo. In entrambi i casi, anche dopo molti test, i file sono stati riempiti con valori NULL (anziché dati arbitrari). Non sono sicuro che si tratti di un disco pulito o di una creazione ottimizzata a zero zero sotto il cofano. – Abel

+0

Buon posto - molto interessante. Posso confermare lo stesso sul mio; Potrei azzardare un'ipotesi che è improbabile che sia un disco pulito nel mio caso (disco rigido disordinato e pieno!) –

2

Perché non utilizzare la classe BackgroundWorker per raggiungere questo obiettivo, dato che puoi passare qualsiasi cosa nel metodo ReportProgress per indicare il rapporto sullo stato. Vedere l'esempio di seguito:

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

Si tratta di un progetto di massima ... Spero che questo aiuti, i migliori saluti, Tom.