C# IO Stream stream (3) base class finishing

1. Namespace System.IO

The I/O operations in C# all belong to the System.IO namespace. In this namespace, C# defines file-related classes, various streams, decorator streams, adapters, and other related structures.

In the namespace starting with System.IO, C# further expands IO and provides stream compression and decompression ( System.IO.Compression ),

Searches and enumerates file system elements ( System.IO.Enumeration ), provides classes for working with memory-mapped files ( System.IO.MemoryMappedFiles ), and more.

2. C# IO Stream base class

In C#, all streams are inherited from the Stream class. The Stream class defines the behavior and attributes that the stream should have, so that developers can ignore the specific details of the underlying operating system and basic equipment. C#'s processing of streams ignores the difference between reading streams and writing streams, making it more like a pipeline for data communication. Streams involve three basic operations:

Read - transfer data from a stream to a data structure Write - write data from a data source to a stream Find - find and modify the current position of an operation in a stream Due to the nature of the stream, not all streams may support it These three operations, so Stream provides three attributes to facilitate confirmation whether the stream supports these three operations:

public abstract bool CanRead { get; } // 获取指示当前流是否支持读取的值

public abstract bool CanWrite { get; } // 获取指示当前流是否支持写入功能的值

public abstract bool CanSeek { get; } // 获取指示当前流是否支持查找功能的值

The above three attributes are determined by the subclass according to its own characteristics whether it supports reading, writing, and searching. Maybe the three attributes will not be true, but they will definitely not be false.

Here are some common streams:

  1. FileStream A stream used to manipulate files
  2. MemoryStream operates on a stream of memory
  3. BufferedStream cache stream, used to enhance the operation performance of other streams
  4. NetworkStream streams that operate on network sockets
  5. PipeStream for reading and writing over anonymous and named pipes
  6. CryptoStream for linking data streams to cryptographic transformations

Let's skip the content that will be introduced later, let's take a look at the important properties and methods in the Stream class:

1. The length of the data in the stream

public abstract long Length { get; }

When the CanSeek of the Stream object is true, that is, when the stream supports searching, you can use this property to confirm the length of the stream, that is, how many bytes of data there are.

2. Stream location

public abstract long Position { get; set; }

Same as the precondition of the length, when the Stream object supports searching, you can use this attribute to confirm or modify the stream position.

3. Read the data in the stream

public abstract int Read (byte[] buffer, int offset, int count);

public virtual int ReadByte ();

这是两种不同的读取方式,第一种是每次读取多个字节的数据,第二个是每次只读一个字节的数据。这里来细细讲解一下区别:

public abstract int Read (byte[] buffer, int offset, int count);

表示流每次最多读取count个字节的数据,然后将数据放到buffer中,位置从下标为offset开始,并返回实际读取的字节数,如果流已经读完了,则返回0。这个过程中,Position会后移实际读取长度,如果流支持搜索,程序中可以调用这个属性。

So here is a limitation like this:

offset + count <= buffer.Length, in other words, offset + maximum number of reads cannot be greater than the length of the buffer array.

Because this method returns an actual read length, someone may judge whether the read is finished: according to the ratio of the returned result to count, if the returned length is less than count, it is considered that the stream has been read; otherwise, the stream has not been read.

Some streams may achieve this effect, but many streams cannot use this as a basis to judge whether the stream has been read. Maybe the length of a certain read is less than count, and then read again to find that there is more data. This is because IO is a time-consuming operation in the system. In most cases, the performance of IO is far from the operation speed of the program. So often there will be such a situation: the length of the stream is 100, and a buffer byte array with a length of 100 is given, and then 10 bytes are read for the first time, and 5 bytes are read for the second time, so that Read the 100 bytes bit by bit.

Therefore, the return value of 0 must be used as the basis for judging the read completion of the stream.

public virtual int ReadByte ();

This method is very simple. It reads one byte of data from the stream each time, and returns -1 if the reading is complete. Some people may be confused. This method obviously reads a byte, that is, a byte, so why is the return type int? Very simple, because byte does not have negative numbers, but int does. Therefore, when the return value is not equal to -1, you can safely convert the type to byte.

4. Write data to the stream

public abstract void Write (byte[] buffer, int offset, int count);

public virtual void WriteByte (byte value);

流的写入与读取相比就简单多了,至少我们不用判断流的位置。现在简单分析一下:

public abstract void Write (byte[] buffer, int offset, int count);

表示从buffer的offset下标开始,取count个字节写入流里。所以,对offset、count的限制依旧,和不能大于数组的长度。写入成功,流的位置会移动,否则将保持现有位置。

public virtual void WriteByte (byte value);

这个方法就更简单了,直接写一个字节给流。

5. Close or destroy the stream

After the operation of the stream is completed, it needs to be closed to release resources such as files or IO devices held by the stream. When many people use a computer, they cannot use QQ to send an excel file that has been opened locally. It will prompt that the file is occupied and cannot be transferred. This is because Excel opens the file and holds a file-related stream, so QQ cannot send it. The solution is very simple, just turn off the excel software. Back to the present, that is, we must close the stream when we are done using it.

So how do we close the stream? Call the following method:

public virtual void Close ();

C#虽然设置了Close方法,但是并不支持开发者在编写程序的时候手动调用Close方法,更推荐使用:

public void Dispose ();

这个方法会将释放流所持有使用的资源,并关闭流。

当前需要注意的一个地方是,在把流关闭或释放之前把流里的数据推送到基础设备,即调用:

public abstract void Flush ();

Some streams have an automatic push function, and you don't need to manually call this method if you encounter such a stream.

For a stream, once it is destroyed or closed, the stream cannot be used again , so an error will be reported if you try to read/write the stream again after calling Close and Dispose.

More:

C# IO Stream stream (2) extension class_wrapper



C# IO Stream Stream (1) Basic Concept_Basic Definition

C# Reflection (1) Basic Concepts

Guess you like

Origin blog.csdn.net/u011127019/article/details/131867746