SoFunction
Updated on 2025-03-08

C# Read files in detail

C# encapsulates almost all classes we can think of and we didn't expect. Streams are a general method to read files. So will you really use it to read data in files? Can you really read it completely?

Usually we use the following steps to read a file:

1. Declare and instantiate a file stream object using OpenRead of File, just like the following

Copy the codeThe code is as follows:

FileStream fs = (filename);

or
Copy the codeThe code is as follows:

FileStream fs = FileStream(filename, , , );

2. Prepare a byte array to store the contents of the file and get the actual size of the file, just like the following byte[] data = new byte[];

3. Wow! Start reading, call a method of a file stream to read data into the data array (data, 0, );

hehe! We only wrote 3 sentences to read the contents in the file intact. It's so concise! Can this code really work as you expected?

The answer is: Almost OK! In most cases, the above code works very well, but we should note that the Read method has a return value. Since there is a return value, it must make sense. If you follow the above writing method, it can be a function without a return value. I think the purpose of returning the value is to give us a chance to judge the size of the actual read file, so as to determine whether the file has been fully read. So the above code cannot guarantee that we must have read all the bytes in the file (although in many cases it is finished). The following method provides a safer method than the above method to ensure that the file is fully read out.

Copy the codeThe code is as follows:

public static void SafeRead (Stream stream, byte[] data)

{

int offset=0; int remaining = ; // Read it continuously as long as there are remaining bytes

while (remaining > 0)

{

int read = (data, offset, remaining);

if (read <= 0) throw new EndOfStreamException("File read to "+()+" failed!"); // Reduce the remaining number of bytes remaining -= read; // Increase the offset offset += read;

}

}


In some cases you don't know the actual length of the stream, such as: network stream. At this time, you can use a similar method to read the stream until the data inside the stream is fully read out. We can first initialize a cache, and then write the stream information read from the stream into the memory stream, just like this:
Copy the codeThe code is as follows:

public static byte[] ReadFully (Stream stream)

{

// Initialize a 32k cache

byte[] buffer = new byte[32768];

using (MemoryStream ms = new MemoryStream()){

//After returning the result, the Dispose method called the object will be automatically recycled and released memory will be released by calling the memory.

// Read while (true){

int read = (buffer, 0, ); // until the last read

3M data can return the result

if (read <= 0) return ();

(buffer, 0, read); }

}}


Although the above examples are relatively simple and the effect is not very obvious (most of them are correct), maybe you have known it a long time ago, it doesn’t matter. This article was originally written for beginners. The following method provides a way to read a stream using a specified cache length. Although in many cases you can directly use the length of the stream, not all streams can be obtained.
Copy the codeThe code is as follows:

public static byte[] Read2Buffer (Stream stream, int BufferLen)

{

// If the specified invalid length buffer is specified, a default length is specified as the cache size

if (BufferLen < 1){ BufferLen = 0x8000; }

// Initialize a cache area byte[] buffer = new byte[BufferLen]; int read=0; int block;

// Every time you read the cache size data from the stream, you know that all streams have been read

while ( (block = (buffer, read, -read)) > 0)

{

// Reset the read position read += block;

// Check whether the cache boundary has reached and check whether there is still information that can be read

if (read == ){

// Try to read a byte int nextByte = ();

// If the read fails, it means that the read is completed, and the result can be returned if (nextByte==-1){ return buffer; }

// Resize the array and prepare to continue reading

byte[] newBuf = new byte[*2]; (buffer, newBuf, );

newBuf[read]=(byte)nextByte; buffer = newBuf;

// Buffer is a reference (pointer), which is intended to reset the buffer pointer to a larger memory read++; }

} // If the cache is too large, use ret to shrink the buffer read in the previous while.


Then return directly
Copy the codeThe code is as follows:

byte[] ret = new byte[read];

(buffer, ret, read); return ret;}