Buffer is required for Network reading, which is an array of byte. After the buffer is allocated, it occupies a fixed memory, and the size setting is not enough. The size setting is too large, resulting in waste and frequent creation may affect the performance;
Buffer must be reused. Currently, two methods are available:
1. buffer Object pool, which is used by WCF;
2. buffer segmentation, that is, ArraySegment <byte>;
No matter the method above, you need to pay attention to the buffer during the call, such as array splitting, but also worry about offset and so on. For example:
byte[] buffer = new byte[512]; Stream stream = new MemoryStream(); stream.Read(buffer, 0, buffer.Length); stream.Write(buffer, 0, buffer.Length);
To be reused:
BufferSegment seg = new BufferSegment(); byte[] buffer = seg.Take(); try { Stream stream = new MemoryStream(); stream.Read(buffer, 0, buffer.Length); stream.Write(buffer, 0, buffer.Length); } finally { seg.Return(buffer); }
For the caller, it depends on the buffer taking object, that is, the BufferSegment above, and must also write try-finally. If the problem persists, the SqlConnection connection pool is in. when Dispose () is returned, if no. dispose () may cause insufficient connections.
BufferSegment seg = new BufferSegment(); using(Buffer item = seg.Take()) { byte[] buffer = item.Array; Stream stream = new MemoryStream(); stream.Read(buffer, 0, buffer.Length); stream.Write(buffer, 0, buffer.Length); }
This method hides both take and return, but still relies on the BufferSegment object;
It was accidentally discovered that Stream 4.0 added a CopyTo method, so the extension was as follows ~
public void CopyTo(Stream destination, int bufferSize)
Only buffersize is exposed to the outside. As for how the buffer comes and how it goes, it is hidden to reduce dependencies!
public static void FixedCopyTo(this Stream instance, Stream destination, int length, Func<bool> perAction = null) { Contract.Requires(instance != null && instance.CanRead); Contract.Requires(destination != null && destination.CanWrite); B buffer; BufferSegment.MemoryBuffer.Take(out buffer); try { int read; while (length > 0 && (read = instance.Read(buffer.Array, buffer.Offset, Math.Min(buffer.Count, length))) != 0) { destination.Write(buffer.Array, buffer.Offset, read); length -= read; if (perAction != null && !perAction()) { break; } } } finally { BufferSegment.MemoryBuffer.Return(ref buffer); } }
These logics are hidden inside !!!Directly copyto when calling.
If there is only one regret, both the source object and the target object need to be packaged as Stream. For example, You Need To package byte [] into MemoryStream at the beginning, however, the memory size of byte [512] and new MemoryStream (byte [512]) cannot contain several bytes,
BufferSegment seg = new BufferSegment(); byte[] buffer = seg.Take(); try { System.Net.Sockets.Socket sock = new System.Net.Sockets.Socket(); int recv = sock.Receive(buffer); Stream stream = new MemoryStream(); stream.Write(buffer, 0, recv); } finally { seg.Return(buffer); }
You can replace it
System.Net.Sockets.Socket sock = new System.Net.Sockets.Socket(); var netStream = new System.Net.Sockets.NetworkStream(sock); Stream stream = new MemoryStream(); netStream.FixedCopyTo(stream);
Take a closer look at the objects in. netframework. Encryption and compression files are all Stream objects, so many objects are used and cool ~~~
Now I don't even want to touch byte .. When you see it, you want to convert it into a MemoryStream ~