Reading Files
Read files without causing memory leaks.
We'll cover the following
Introduction
The best example of an unmanaged resource is a file that resides on a disk. To open it, read it, write to it, or delete it, any programming language must ultimately settle with operating system calls. Because the operating system doesn’t run on top of the CLR, OS calls are considered unmanaged code. Therefore, we must dispose of objects that use such external calls appropriately. Before we start the creation and disposal of file objects, we must first understand how .NET works with files.
The Stream
class
A file is nothing but a sequence of bytes. Depending on the file format, this sequence is interpreted differently and the user sees a meaningful output. If we interpret an image as a text, then we get some gibberish output.
In .NET, a sequence of bytes is represented by the Stream
class inside the System.IO
namespace. It’s an abstract base class for all streams inside .NET. There are two main operations provided by streams:
- Reading: This represents the transfer of bytes from the external environment (file, network connection, keyboard) into the program. For instance, we can read from the stream and save everything as an array of bytes (
byte[]
). - Writing: This represents the transference of bytes from the application to the external environment (from
byte[]
to a file, network connection, or an output device).
Depending on the source of a byte sequence, there are various Stream
types in .NET. For network access, for example, we have NetworkStream
, and for files, we have FileStream
. In this lesson, we’re interested in the latter.
Reading with FileStream
The FileStream
class provides a stream to interact with a file. It supports read and write operations in both synchronous and asynchronous manners. With FileStream
, we can work with both text and binary files.
To create an instance of FileStream
, we can use one of the FileStream
constructors:
var fileStream = new FileStream(path, mode);
path
(string
object) is the location of the file we want to open, and mode
is an enumeration of type FileMode
that can have one of the following values:
-
Append
: If the file exists, the text is appended to the end of the file. If the file doesn’t exist, then it’s created. The file is opened only for writing. -
Create
: A new file is created. If a file with the same name already exists, then it’s overwritten. -
CreateNew
: This attempts to create a new file and open it. An exception is thrown if a file with the same name already exists. -
Open
: This opens the file and throws an exception if no such file exists. -
OpenOrCreate
: This opens the file or creates a new one if it doesn’t exist. -
Truncate
: This attempts to open an existing file and overwrite it.
Before using a FileStream
object to read a file, let’s first take a look at the files we have at our disposal. For that, we can make use of the Directory
static class, which lets us interact with the directory structure:
Get hands-on with 1400+ tech skills courses.