One common error when using streams is copying a byte at a time or using a small buffer. In most cases, a search is performed to write data to disk, so using a larger buffer will decrease the average search time per byte.
Operating systems write files to disk in clusters. This means that when writing one byte to a disk, Windows will actually write a block ranging in size from 512 to 64 kb. You can get much better disk performance by using a buffer that is an integer multiple of 64kb.
In addition, you can get the boost from using a buffer that is a multiple of your processors, which are at the heart of the memory page size. For x86 / x64 computers, this can be set as 4kb or 4mb.
So you want to use an integer multiple of 4mb.
, -, .
class Downloader
{
const int size = 4096 * 1024;
ManualResetEvent done = new ManualResetEvent(false);
Socket socket;
Stream stream;
void InternalWrite(IAsyncResult ar)
{
var read = socket.EndReceive(ar);
if (read == size)
InternalRead();
stream.Write((byte[])ar.AsyncState, 0, read);
if (read != size)
done.Set();
}
void InternalRead()
{
var buffer = new byte[size];
socket.BeginReceive(buffer, 0, size, System.Net.Sockets.SocketFlags.None, InternalWrite, buffer);
}
public bool Save(Socket socket, Stream stream)
{
this.socket = socket;
this.stream = stream;
InternalRead();
return done.WaitOne();
}
}
bool Save(System.Net.Sockets.Socket socket, string filename)
{
using (var stream = File.OpenWrite(filename))
{
var downloader = new Downloader();
return downloader.Save(socket, stream);
}
}