2009-12-07 18 views
65

Załóżmy, że piszę kilka plików na dysk, od 2 MB do 5 GB. Jakie są sensowne wartości buforów dla obiektu FileStream?C# FileStream: Optymalny rozmiar bufora do pisania dużych plików?

Czy rozsądnie jest pracować z buforami o wielkości kilku megabajtów, czy też powinienem trzymać się buforów kilobajtowych?

+1

Dlaczego nie pozwolić .NET obsłużyć bufora i po prostu napisać, jak trzeba? – cjk

+1

Po prostu spróbuj. Napisz mały test porównawczy, używając StopWatch i podaj nam wyniki. –

+4

Podejrzewam, że "bufor", o którym mowa, to bufor, który musisz zadeklarować, gdy jesteś np. kopiowanie z jednego strumienia do drugiego (tj. ile bajtów odczytałeś ', a następnie' Write' w jednej iteracji). –

Odpowiedz

43

Domyślny rozmiar bufora to 4 KiB.

Również spojrzeć tutaj: Sequential File Programming Patterns and Performance with .NET

+2

http://msdn.microsoft.com/en-us/library/dd783870.aspx Domyślny rozmiar to '4096' bajtów – VMAtm

+3

Właśnie zdekompilowany System.IO.FileStream. wewnętrzna const int DefaultBufferSize = 4096; – Vladimirs

+2

@VMAtm - to referencja jest nieprawdziwa (jeśli chodzi o odpowiedź na pytanie o to, co klasa FileStream normalnie używa wewnętrznie). Rozmiar bufora CopyTo jest znacznie większy, dokładnie 80 KiB. Napisałem o niektórych cechach wydajności pliku IO .NET tutaj (http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write/19692949#19692949) –

30

Szybkie trochę odniesienia na podstawie dokumentu powołanego nie wykazuje wzrost wydajności w moim systemie większych niż rozmiar bufora 128KB. Twój przebieg może się różnić, skorzystaj z poniższego.

 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 dla testu porównawczego kod, ale OP zażądał wielkości bufora zapisu. Podejście jest jednak dobre. –

+1

Hm, twój komentarz zaprzecza sam sobie. Mówisz 'size = 256 KB', ale jednocześnie mówisz' i = 18', a '2 << 18' ma w rzeczywistości 512 KB. – Timwi

+0

2 << 18 == 262144 bajtów 1024 bajtów w kilo bajcie, zatem 256 KB. czego mi brakuje? – Firestrand

Powiązane problemy