SoFunction
Updated on 2025-03-08

.Net Notes: Detailed explanation of the use of Stream

Stream in msdn: provides a generic view of a sequence of bytes. This explanation is too abstract and difficult to understand; it is easier to understand from the literal meaning of stream "river, water flow". stream is an abstract class that defines some unified behaviors of things like "water flow", including whether this "water flow" can be pumped out (read the flow content); whether it can be poured into this "water flow" (write content into the flow); and how long the "water flow" is; how to turn off the "water flow", how to pour water into the "water flow", and how to pump water from the "water flow".
Commonly used Stream subclasses are:
1) MemoryStream byte stream stored in memory
2) FileStream The byte stream stored in the file system
3) NetworkStream byte streams read and write through network devices
4) BufferedStream provides buffered streams for other streams
Stream provides a way to read and write streams by reading content from the stream in bytes. We often use reading or writing text from byte streams. Microsoft provides StreamReader and StreamWriter classes to help us realize the function of reading and writing strings on streams.
Let’s see how to operate Stream, that is, how to read bytes from streams and how to write bytes into streams
1. Use the method to read bytes from the stream, as shown in the following example comment:
Copy the codeThe code is as follows:

using System;
using ;
using ;
using ;
using ;
namespace UseStream
{
    class Program
    {
//Example how to read a byte stream from a stream
        static void Main(string[] args)
        {
            var bytes = new byte[] {(byte)1,(byte)2,(byte)3,(byte)4,(byte)5,(byte)6,(byte)7,(byte)8};
            using (var memStream = new MemoryStream(bytes))
            {
                int offset = 0;
                int readOnce = 4;
                do
                {
                    byte[] byteTemp = new byte[readOnce];
// Use the Read method to read bytes from the stream
//The first parameter byte[] stores the content read from the stream
//The second parameter is the start index stored in the byte[] array,
//The third int parameter is the maximum number of bytes read at a time
//The return value is the number of bytes read this time, and this value is less than or equal to the third parameter
                    int readCn = (byteTemp, 0, readOnce);
                    for (int i = 0; i < readCn; i++)
                    {
                        (byteTemp[i].ToString());
                    }

                    offset += readCn;

//When the actual number of bytes read is less than the set number of reads, it is indicated to the end of the stream
                    if (readCn < readOnce) break;
                } while (true);
            }
            ();
        }
    }
}

2. Use method to read the stream content of FileStream
Note: BeginRead's implementation in some streams is exactly the same as Read, such as MemoryStream; while BeginRead is a real asynchronous operation in FileStream and NetworkStream.
The following example code and comments:
Copy the codeThe code is as follows:

using System;
using ;
using ;
using ;
using ;
using ;
namespace UseBeginRead
{
    class Program
    {
//Define asynchronous read status class
        class AsyncState
        {
            public FileStream FS { get; set; }

            public byte[] Buffer { get; set; }

            public ManualResetEvent EvtHandle { get; set; }
        }
        static  int bufferSize = 512;
        static void Main(string[] args)
        {
            string filePath = "d:\\";
//Open the file stream in read-only
            using (var fileStream = new FileStream(filePath, , ))
            {
                var buffer = new byte[bufferSize];

//Constructing the state that BeginRead needs to be passed
                var asyncState = new AsyncState { FS = fileStream, Buffer = buffer ,EvtHandle = new ManualResetEvent(false)};

//Asynchronous reading
                IAsyncResult asyncResult = (buffer, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);

//Block the current thread until the reading is completed and the signal is sent
                ();
                ();
                ("read complete");
                ();
            }
        }
//Asynchronous read callback processing method
        public static void AsyncReadCallback(IAsyncResult asyncResult)
        {
            var asyncState = (AsyncState);
            int readCn = (asyncResult);
//Judge whether the content has been read
            if (readCn > 0)
            {
                byte[] buffer;
                if (readCn == bufferSize) buffer = ;
                else
                {
                    buffer = new byte[readCn];
                    (, 0, buffer, 0, readCn);
                }

//Output read content value
                string readContent = Encoding.(buffer);
                (readContent);
            }

            if (readCn < bufferSize)
            {
                ();
            }
            else {
                (, 0, bufferSize);
//Perform asynchronous read operation again
                (, 0, bufferSize, new AsyncCallback(AsyncReadCallback), asyncState);
            }
        }
    }
}

3. Use method to write byte arrays into stream
When using the Write method, you need to first use the Stream's CanWrite method to determine whether the stream is writable. The following example defines a MemoryStream object, and then writes a byte array into the memory stream.
Copy the codeThe code is as follows:

using System;
using ;
using ;
using ;
using ;
namespace UseStreamWrite
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ms = new MemoryStream())
            {
                int count = 20;
                var buffer = new byte[count];
                for (int i = 0; i < count; i++)
                {
                    buffer[i] = (byte)i;
                }

//Set the current position of the stream to the starting point of the stream
                (0, );

                ("ms position is " + );

//Note that before calling Stream's Write method, use CanWrite to determine whether the Stream is writeable
                if ()
                {
                    (buffer, 0, count);
                }

//If you write correctly, the position of the stream will move to the write start position plus the number of bytes written
                ("ms position is " + );
            }

            ();
        }
    }
}

4. Use asynchronous writing; asynchronous writing can improve program performance, because the speed of disk or network IO is much smaller than that of CPU, and asynchronous writing can reduce the waiting time of CPU.
The following example of using FileStream to write files asynchronously
Copy the codeThe code is as follows:

using System;
using ;
using ;
using ;
using ;
using ;
namespace UseStreamBeginWrite
{
    class Program
    {
        /// <summary>
/// Parameter encapsulation class required for asynchronous callbacks
        /// </summary>
        class AsyncState {
            public int WriteCountOnce { get; set; }
            public int Offset { get; set; }
            public byte[] Buffer { get; set; }
            public ManualResetEvent WaitHandle { get; set; }
            public FileStream FS { get; set; }
        }
        static void Main(string[] args)
        {
//Prepare a 1K byte array
            byte[] toWriteBytes = new byte[1 << 10];
            for (int i = 0; i < ; i++)
            {
                toWriteBytes[i] = (byte)(i % );
            }
            string filePath = "d:\\";
//FileStream instance
            using (var fileStream = new FileStream(filePath, , , ))
            {
                int offset = 0;
//Write 32 bytes each time
                int writeCountOnce = 1 << 5;
//The state required to construct the callback function
                AsyncState state = new AsyncState{
                    WriteCountOnce = writeCountOnce,
                    Offset = offset,
                    Buffer = toWriteBytes,
                    WaitHandle = new ManualResetEvent(false),
                    FS = fileStream
                };

//Do asynchronous writing operations
                (toWriteBytes, offset, writeCountOnce, WriteCallback, state);

//Waiting for the continued signal sent by waiting for the writing or error
                ();
            }
            ("Done");
            ();
        }
        /// <summary>
/// Asynchronously written callback function
        /// </summary>
/// <param name="asyncResult">Write status</param>
        static void WriteCallback(IAsyncResult asyncResult)
        {
            AsyncState state = (AsyncState);

            try
            {
                (asyncResult);
            }
            catch (Exception ex)
            {
                ("EndWrite Error:" + );
                ();
                return;
            }

            ("write to " + );
//Judge whether it is finished, continue to write asynchronously if it is not finished.
            if ( + < )
            {
                += ;
                ("call BeginWrite again");
                (, , , WriteCallback, state);
            }
            else {
//Send a completion signal after writing
                ();
            }
        }
    }
}