A stream is a sequence of bytes traveling from a source to a destination over a communication medium. Streams can either be input stream or output stream. The input stream is used for reading while the output stream is used for writing. |
|
Note: This stream concept does not just apply to files. It holds true for communication over a network through sockets too. |
|
File System Classes |
|
.NET provides a lot of classes for handling files. These are contained in the System.IO namespace. Listed below are various classes under this namespace.The given list of various classes comes under the System.IO namespace. |
|
Class Name |
Description |
FileStream |
Is used to read from and write to any location within a file. |
BinaryReader |
Is used to read primitive data types in the form of binary data from the stream. |
StreamReader |
Is used to read characters from a byte stream. |
StringReader |
Is used to read data from a string buffer. |
BinaryWriter |
Is used to write primitive data types in the form of binary data to the stream. |
StreamWriter |
Is used to write characters to a byte stream. |
StringWriter |
Is used to write data to a string buffer. |
BinaryReader |
Is used to read primitive data types in the form of binary data from the file stream. |
StreamReader |
Is used to read characters from the a byte stream. |
DirectoryInfo |
Is used to perform operations on directories. |
FileInfo |
Is used to perform operations on files. |
|
|
FileStream Class |
|
The FileStream class resides under the System.IO namespace and is derived from the abstract class Stream. It supports random access through seeking. Before you begin reading from and writing to a file, an object of the FileStream class needs to initialize. The parameterized constructor of this class allows to create/open files and setting up appropriate file sharing modes.The FileStream constructor contains four types of parameters. |
|
Creating a new file |
|
FileStream fs = new FileStream
(
"TestFile.txt",
FileMode.Create,
FileAccess.Write,
FileShare.Read
);
|
|
Note: The code is spanned across multiple lines for the sake of clarity. |
|
The first parameter to the constructor is the path to the file. In this case the new file will be created in the working directory of the application. . A complete path such as C:\Program Files\eBIZ\Tutorials\C-Sharp\Chapter-15\TestFile.txt can also be used. Backslash being the escape sequence starter would need to be escaped in the string. The code would look something like:- |
|
FileStream fs = new FileStream
(
"C:\\Program Files\\Maxotek\\
Tutorials\\C-Sharp\\Lesson14\\TestFile.txt",
FileMode.Create,
FileAccess.Write,
FileShare.Read
);
|
|
Other technique of doing this, to use @ character before the string. This prevents any escape sequence character as the backslash itself is taken as a normal character. |
|
FileStream fs = new FileStream
(
@"C:\Program Files\Maxotek\Tutorials\C-Sharp\Lesson14\TestFile.txt",
FileMode.Create,
FileAccess.Write,
FileShare.Read
);
|
|
The second parameter to the constructor is the FileMode enumeration. It can have any of the following values. |
|
File Mode
|
Description
|
Create |
Creates a new file or truncates the existing file. |
CreateNew |
Creates a new file. If the file already exists, throws a System.IO.IOException. |
Open |
Opens an existing file. Throws a System.IO.FileNotFoundException if the file does not exist. |
OpenOrCreate |
Opens an existing file or creates a new one. The difference between this mode and the Create mode is that it does not truncate the file. |
Append |
Opens the file and seeks to the end. A new file is created if the file does not exist. |
Truncate |
Opens an existing file and truncates its content so that the file size becomes zero. Attempting to read in this mode throws an exception. |
|
|
The third parameter is the FileAccess which specifies whether the file is to be opened for Reading (FileAccess.Read), Writing (FileAccess.Write) or both (FileAccess.ReadWrite). |
|
The fourth and last parameter is FileShare mode which states how the file will be shared. |
|
FileShare Mode
|
Description
|
Read |
Allows other handles to read from the file. |
Write |
Allows other handles to write to the file. |
Delete |
Allows subsequent deleting of the file. |
Inheritable |
Makes the file handle inheritable to child processes. |
None |
Declines sharing of file. No other process can open the file until it is closed. |
|
|
Note: The constructor is overloaded into many other forms which take various other types and combinations of parameters. The above form was one of the basic ones. |
|
Writing to the File |
|
We use the StreamWriter class which is inherited from the abstract class TextWriter to write a series of characters. After opening the file in the appropriate mode (Write or ReadWrite in this case), a new object of the StreamWriter class is created. The object of the FileStream class is passed to it, hence associating the stream with the file. |
|
After this, the content can be written to the file by using Write () or the WriteLine () method.. WriteLine appends an end of line to the content. These two methods are highly overloaded to enable almost all built in data types to be directly written. |
|
Once you have done all the writing, make sure you close the file using the Close method. This ensures all the content is physically written to the file. For performance reasons, the write operation is buffered and sometimes the content might not be physically written to the file even after the Write method was called. To force all the buffers to be cleared and all buffered content to be written to the underlying stream (File in our case), use the Flush method. |
|
FileStream fs = new FileStream
(
"TestFile.txt",
FileMode.Create,
FileAccess.Write,
FileShare.Read
);
StreamWriter sw = new StreamWriter(fs);
sw.Write("Hello World");
sw.Close(); // Close the Stream
fs.Close(); // Close the File
|
|
Example for Writing to a Text File |
|
using System;
using System.IO;
namespace csharp_station.howto
{
class TextFileWriter
{
static void Main(string[] args)
{
// create a writer and open the file
TextWriter tw = new StreamWriter("date.txt");
// write a line of text to the file
tw.WriteLine(DateTime.Now);
// close the stream
tw.Close();
}
}
}
|
|
The above program creates a text file when it runs. In the directory where the executable program is located, you’ll find a file named date.txt. If you view the contents of this file, you’ll see the following textual representation of the date and time when the program last ran: |
|
2/15/2002 8:54:51 PM |
|
The first task in this example is to open the file. This happens by instantiating a StreamWriter class, which returns an object of type TextWriter. The result could have also been assigned to a StreamWriter instance. The StreamWriter was called with a single parameter, indicating the name of the file to open. |
|
If this file doesn’t exist, the StreamWriter will create it. The StreamWriter also has 6 other constructor overloads that permit you to specify the file in different ways, buffer info, and text encoding. Here’s the line that opens the date.txt file: |
|
TextWriter tw = new StreamWriter(“date.txt”); |
|
Using the TextWriter instance, tw, you can write text info to the file. The example writes the text for the current date and time, using the static Now property of the DateTime class. Here’s the line from the code: |
|
tw.WriteLine(DateTime.Now); |
|
When you’re done writing to the file, be sure to close it as follows: |
|
tw.Close(); |
|
Reading from a fie |
|
The StreamReader class is used to read a series of characters from a FileStream. This StreamReader is derived from the abstract class TextReader. Before reading, the file must be opened in the appropriate mode (Read or ReadWrite). |
|
To Read the next character or the next set of characters, use the Read() method. This method has two forms. One that does not take any parameters and reads the next character. It returns the byte value of the character. The other method takes three parameters:- |
|
• An array of characters – The read characters are stored in the variable passed here.
• The index of the buffer at which to begin writing
• Maximum number of characters to read |
|
The ReadLine() method reads a line of characters and returns the result in the form of a string. |
|
FileStream fs = new FileStream
(
"TestFile.txt",
FileMode.Open,
FileAccess.Read,
FileShare.Read
);
StreamReader sr = new StreamReader(fs);
string str = sr.ReadLine();
while (str != null)
{
Console.WriteLine(str);
str = sr.ReadLine();
}
sr.Close(); // Close the Stream
fs.Close(); // Close the File
|
|
The file pointer can be seeked to any position of the file using the BaseStream property’s Seek method. This method takes two parameters. The first, a byte offset relative to the Origin (second) parameter. |
|
This value can be either positive which moves the pointer downwards the file or negative which moves the file pointer upwards the file. The second parameter known as the Origin parameter indicates the reference point to obtain the new position. The permissible values are Begin, Current and End. |
|
The following line of code moves the file pointer to the 5th character from the beginning. |
|
sr.BaseStream.Seek(5, SeekOrigin.Begin); |
|
Moves the pointer to the start. |
|
sr.BaseStream.Seek(0, SeekOrigin.Begin); |
|
Moves the pointer to 5 characters ahead of the current position. |
|
sr.BaseStream.Seek(5, SeekOrigin.Current); |
|
Moves the pointer 5 characters backward from the current position. |
|
sr.BaseStream.Seek(-5, SeekOrigin.Begin); |
|
Moves the pointer to the end. |
|
sr.BaseStream.Seek(0, SeekOrigin.End); |
|
The Peek method is used to read the next character without consuming it, i.e the file pointer does not move ahead. |
|
Example for Reading From a Text File |
|
using System;
using System.IO;
namespace csharp_station.howto
{
class TextFileReader
{
static void Main(string[] args)
{
// create reader & open file
Textreader tr = new StreamReader("date.txt");
// read a line of text
Console.WriteLine(tr.ReadLine());
// close the stream
tr.Close();
}
}
}
|
|
In the above example, the text file is opened in a manner similar to the method used in previous example, except it uses a StreamReader class constructor to create an instance of a Textreader. The StreamReader class includes additional overloads that allow you to specify the file in different ways, text format encoding, and buffer info. This program opens the date.txt file, which should be in the same directory as the executable file: |
|
Textreader tr = new StreamReader(“date.txt”); |
|
Within a Console.WriteLine statement, the program reads a line of text from the file, using the ReadLine() method of the Textreader instance. The Textreader class also includes methods that allow you to invoke the Read() method to read one or more character or use the Peek() method to see what the next character is without pulling it from the stream. Here’s the code that reads an entire line from the text file: |
|
Console.WriteLine(tr.ReadLine()); |
|
When done reading, you should close the file as follows: |
|
tr.Close(); |
|
Implementing Binary Read & Write |
|
The StreamReader and StreamWriter classes work with character data. In this mode everything is written as plain text. To implement binary operations, wherein a number such as 327.68 would be written as a float value consuming four bytes and not just as plain text, we need to use the BinaryReader and BinaryWriter classes. |
|
They are very similar to their text counterparts except that no Line (ReadLine and WriteLine) methods are provided. The BinaryReader class also supports data type specific methods such as ReadInt32, ReadDouble, etc. These allow you to directly read the content from the file in the appropriate format. If we were to use the StreamReader class, we would have to convert the string to integer or double format using the Convert.ToInt32 and Convert.ToDouble() methods. |
|
Writing to File |
|
int MyNumber = 69;
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(MyNumber);
|
|
Reading from file |
|
BinaryReader br = new BinaryReader(fs);
int MyNumber = br.ReadInt32(); |
|
Implementing the Windows File System |
|
Often we need to browse directories and locate files. Many such operations can be accomplished by using the two classes – DirectoryInfo and FileInfo. Both of these are derived from the FileSystemInfo class. |
|
The tables below list some of the commonly used properties and methods corresponding to both of these classes. |
|
Properties of DirectoryInfo Class |
|
Property |
Description |
Attributes |
Gets or sets attributes associated with the current directory. |
CreationTime |
Gets or sets the Creation time of the directory. |
Exists |
Gets a Boolean value indicating whether the directory exists |
FullName |
Gets a string containing the full path of the directory. |
LastAccessTime |
Gets the last accessed time of the directory. |
Name |
Gets a string containing the name of the directory. |
|
|
Methods of DirectoryInfo Class |
|
Method |
Description |
Create |
Creates a directory. |
Delete |
Deletes a directory. |
GetDirectories |
Returns the directories in the current directory. Supports filtering and recursive listing. |
GetFiles |
Returns the file in the current directory. |
|
|
Properties of FileInfo class |
|
Property |
Description |
Attributes |
Gets or sets the attributes associated with the current file. |
CreationTime |
Gets or sets the CreationTime of the file. |
Directory |
Gets an instance of the directory to which the file belongs to. |
Exists |
Gets a Boolean value indicating whether the file exists. |
Extension |
Gets a string containing the extension of the file. |
FullName |
Gets a string containing the full path to the file. |
LastAccessTime |
Gets the last access time of the file. |
LastWriteTime |
Gets the time of the last wriiten activity on the file. |
Length |
Gets the length of the file in Bytes. |
Name |
Gets the name of the File. |
|
|
Methods of FileInfo class |
|
Method |
Description |
Create |
Creates a new file. |
AppendText |
Appends a text to the file. |
Delete |
Deletes the file. |
Open |
Opens the file. |
OpenRead |
Opens a file in the read-only mode. |
|
|
|