Tweets

Open And Read A File Using C#

2022-08-10 02:59 AM @sirpenski
2022-08-10 02:59 AM
   
Copy   Embed   Share


Opening and existing file in read only mode and then loading the contents into memory is supposed to be one of the easiest things to do using C#. It turns out that is not; especially in high capacity situations (asp.net core webserver) or for cases when reading large files is necessary.

The solution provided consists of two functions; a read bytes function and a read text function. Both functions are async and the read bytes function DOES NOT implement the using clause; as that relies on garbage collection on a stream which is not timely enough for high capacity environments.

Note too that the entire contents of the file are read into memory. This is required for encryption, decryption purposes, image processing, etc. Note too that the sequential steps are shown. ie it is not a one line cryptic programmer chest thump statement. Also, please don't confuse this with FileStreamResult as that is a totally different beast. The code is shown below.


// -------------------------------------------------------------------------------
// This function reads bytes from a file and returns a byte array containing the
// the full file contents
// -------------------------------------------------------------------------------

public async Task<byte[]> ReadBytesAsync(string Filename, int BufSize = 64 * 1024)
{

  // dim the byte array
  byte[] rt = new byte[0];

  // define the filestream
  FileStream fs = null;

  // set up a try catch block just in case
  try
  {
    // open the file stream
    fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read, BufSize);

    // define an array
    byte[] b = new byte[fs.Length];

    // read bytes
    int bytesRead = fs.Read(b);

    // read the bytes from the file stream
    while (bytesRead > 0)
    {
      // get the current length of the return buffer
      int curRtLength = rt.Length;

      // redim the return buffer to the current length plus the bytes read
      Array.Resize(ref rt, curRtLength + bytesRead);

      // copy the buf b to rt.
      Array.Copy(b, 0, rt, curRtLength, bytesRead);

      // read more from the stream
      bytesRead = fs.Read(b);
    }

  }
  catch (Exception)
  {
    rt = new byte[0];
  }

  // if the filestream is not null, then close, dispose.
  if (fs != null)
  {

    // close it.
    fs.Close();

    // dispose
    await fs.DisposeAsync();

    // null it out
    fs = null;

  }

  // return the byte array
  return rt;
}
     

Shown below is the Read Text Async function. This calls the ReadBytesAsync function above. Note that this function has an encoding parameter. This is important because one might be reading ascii text, Unicode, etc.


// ---------------------------------------------------------------------------------------------
// This function reads a file from the file systems and returns a encoded string representation
// of the file.
// ---------------------------------------------------------------------------------------------

public async Task<string> ReadTextAsync(string fn, Encoding enc = null, int BufSize = 64 * 1024)
{
    // deault to empty string
    string rt = "";

    // default the encoding. Note, UTF8 specified.
    Encoding encoding = Encoding.UTF8;

    // read the encoding parameter (enc)
    if (enc != null) {

      // set the encoding
      encoding = enc;

    }

    // quick file exists check. optional.
    if (File.Exists(fn))
    {

      // set the byte array returned.
      byte[] b = await ReadBytesAsync(fn, BufSize);

      // check for null
      if (b != null)
      {

        // check for length
        if (b.Length > 0)
        {

          // get the string from the byte array
          rt = encoding.GetString(b);
        }
      }
   }

   // return the string
   return rt;
}
  

Usage:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

public async Task<byte[]> GetFileBytes(string fileName)
{
  return await ReadBytesAsync(fileName);
}

public async Task<string> GetFileAsString(string fileName, Encoding encoding)
{
    return await ReadTextAsync(fileName, encoding);
}
  

I hope you find it helpful.

Open Source
Paul F. Sirpenski
Personal Open Source Directory Of Paul F. Sirpenski

ASP.NET Core
Open Source directory Of the Microsoft Asp.Net Core project.