2009-12-07 22 views
65

Farz edelim ki, 2MB ile 5GB arasında diskte birkaç dosya yazıyorum. FileStream için hassas tampon değerleri nelerdir?C# FileStream: Büyük dosyaları yazmak için en uygun arabellek boyutu?

Birkaç megabayt biti ile çalışmak mantıklı mıdır yoksa kilobayt tamponlara yapışmalı mıyım?

+1

Neden .Net arabelleğin işlenmesine izin vermeyin ve gerektiği gibi yazın. – cjk

+1

Sadece dene. StopWatch kullanarak biraz karşılaştırma yapın ve sonuçları bize bildirin. –

+4

Söz konusu "arabellek" söz konusu olduğunda, ör. bir akıştan diğerine kopyalama (yani, bir defada 'Okumak' ve 'Yaz'). –

cevap

43

Varsayılan arabellek boyutu 4 KiB'dir.

Ayrıca burada bir göz atın: Sequential File Programming Patterns and Performance with .NET 128KB tampon boyutundan daha sistemimde Hiçbir artış büyük belge başvurulan gösterileri dayalı

+2

http://msdn.microsoft.com/en-us/library/dd783870.aspx Varsayılan boyut '4096' bayttır – VMAtm

+3

Sadece decompiled System.IO.FileStream. iç const int DefaultBufferSize = 4096; – Vladimirs

+2

@VMAtm - bu başvuru sahte (FileStream sınıfının normalde dahili olarak kullandığı soruyu yanıtlama açısından). CopyTo arabellek boyutu, tam olarak 80 KiB büyüktür. .NET'in bazı IO dosya performans özellikleri hakkında bir değerlendirme yaptım (kıyaslama için http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write/19692949#19692949) –

30

Hızlı bir küçük kriter. Kilometreniz değişebilir, aşağıdakileri kullanmaktan çekinmeyin.

 Stopwatch sw = new Stopwatch(); 
     Random rand = new Random(); // seed a random number generator 
     int numberOfBytes = 2 << 22; //8,192KB File 
     byte nextByte; 
     for (int i = 1; i <= 28; i++) //Limited loop to 28 to prevent out of memory 
     { 
      sw.Start(); 
      using (FileStream fs = new FileStream(
       String.Format(@"C:\TEMP\TEST{0}.DAT", i), // name of file 
       FileMode.Create, // create or overwrite existing file 
       FileAccess.Write, // write-only access 
       FileShare.None,  // no sharing 
       2 << i,    // block transfer of i=18 -> size = 256 KB 
       FileOptions.None)) 
      { 
       for (int j = 0; j < numberOfBytes; j++) 
       { 
        nextByte = (byte)(rand.Next() % 256); // generate a random byte 
        fs.WriteByte(nextByte);    // write it 
       } 
      } 
      sw.Stop(); 
      Console.WriteLine(String.Format("Buffer is 2 << {0} Elapsed: {1}", i, sw.Elapsed)); 
      sw.Reset(); 
     } 
+2

+1 kod ancak OP, yazma arabelleği boyutları sordu. Bununla birlikte, yaklaşım sağlamdır. –

+1

Hm, yorumunuz çelişiyor. Size = 256 KB' deyin, ama aynı zamanda i = 18' ve '2 << 18' aslında 512 KB olduğunu iddia edersiniz. – Timwi

+0

2 << 18 == 262144 bayt 1024 bayt, bir kilo baytında 256 KB'dir. Neyi kaçırıyorum? – Firestrand