c read file details
- 2020-05-17 06:17:00
- OfStack
c# encapsulates almost every class we can think of and no class we can think of. Stream is a way to read files, so would you really use it to read data in files? Can you really read it all?
Normally we read a file using the following steps:
1. Declare and instantiate a file stream object using OpenRead of File, as follows
FileStream fs = File.OpenRead(filename);
or
FileStream fs = FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
2. Prepare a byte array to store the contents of the file. fs.Length will get the actual size of the file, as follows: byte[] data = new byte[fs.Length];
3, wow! To start reading, call 1 method of 1 file stream to read data into data array fs.Read (data, 0, data.Length);
Ha ha! We can read the contents of the document intact after only writing 3 sentences. It is so concise! Can this code really work the way you expect it to?
The answer is: almost! For the most part, the above code works fine, but we should note that the Read method does have a return value, and since it does have a return value, 1 makes sense. It could have been a function with no return value. I think the purpose of the return value is to give us a chance to determine the size of the actual read file so that we can determine whether the file has been completely read. So the code above does not guarantee that we have read all the bytes in the file (although in many cases we have). The following method provides a more secure method than the above one to ensure that the file is fully read
public static void SafeRead (Stream stream, byte[] data)
{
int offset=0; int remaining = data.Length; // Keep reading as long as there are bytes left
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0) throw new EndOfStreamException(" File read to "+read.ToString()+" Failure! "); // Reduce the number of remaining bytes remaining -= read; // Increase offset offset += read;
}
}
There are situations where you don't know the actual length of the flow: network flow. At this point, you can use a similar method to read the stream until the data inside the stream is fully read. We can initialize 1 cache segment and then write the stream information read from the stream to the memory stream, as follows:
public static byte[] ReadFully (Stream stream)
{
// Initialize the 1 a 32k The cache
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream()){
// The result is returned and the call to the object is automatically reclaimed Dispose Method to free memory
// Keep reading while (true){
int read = stream.Read (buffer, 0, buffer.Length); // Until the end of the reading
3M The data can then return the result
if (read <= 0) return ms.ToArray();
ms.Write (buffer, 0, read); }
}}
Although the examples above are simple and the effect is not very obvious (most of them are right), you may already know it, but this article is intended 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 Stream.Length to get the length of the stream, but not all streams can.
public static byte[] Read2Buffer (Stream stream, int BufferLen)
{
// If the specified invalid length of the buffer is specified, specify 1 The cache size is defined as the default length
if (BufferLen < 1){ BufferLen = 0x8000; }
// Initialize the 1 A buffer byte[] buffer = new byte[BufferLen]; int read=0; int block;
// Cache size data is read from the stream each time until all the streams have been read
while ( (block = stream.Read(buffer, read, buffer.Length-read)) > 0)
{
// Reset the read position read += block;
// Check to see if the boundary of the cache has been reached and if there is still information available to read
if (read == buffer.Length){
// Try to read 1 bytes int nextByte = stream.ReadByte();
// A failed read means that the read is complete and the result can be returned if (nextByte==-1){ return buffer; }
// Resize the array to continue reading
byte[] newBuf = new byte[buffer.Length*2]; Array.Copy(buffer, newBuf, buffer.Length);
newBuf[read]=(byte)nextByte; buffer = newBuf;
// buffer is 1 A reference (pointer), which is meant to be reset buffer Pointer to 1 More memory read++; }
} // Use if the cache is too large ret To shrink the front while Read the buffer .
And then go straight back
byte[] ret = new byte[read];
Array.Copy(buffer, ret, read); return ret;}