< FileStream Examples | Main | BinaryWriter & BinaryReader Examples >

 


 

Chapter 2 Part 3:

Managed I/O - Streams, Readers, and Writers

 

 

What we have in this chapter 2 Part 3?

  1. Reading or Writing to a File

  2. Closing a File

  3. C++ Program Example: Writing and reading text – StreamWriter and StreamReader

  4. C# Program Example: Writing and reading text – StreamWriter and StreamReader

 

 

 

Note: If you want to experience a complete C++ .NET/C++-CLI programming tutorial please jump to Visual C++ .NET programming tutorial.

 

Reading or Writing to a File

 

Files are normally constructed as one of two types: text or binary. Text files typically contain printable ASCII and Unicode characters that can normally be viewed using a text reader such as Notepad in Windows. Some examples of text files can be Readme.txt files or even XML files. Binary files, on the other hand, are files that usually contain an ordered set of bytes that are typically not printable. The order (or sequence) of the bytes in a binary file is important to the application that uses the file. An example of a binary file is an MP3 audio file, where bytes are arranged in a sequence to represent encoded audio information. The sequence (or ordering) of bytes in an MP3 file must be ordered in a well-defined way so that an application such as Windows Media Player can play back the audio information correctly. If you try to view a binary file using a text viewer such as Notepad, you’ll most likely see a bunch of garbled characters because many of the bytes will typically not be printable ASCII or Unicode characters.

The basic FileStream class allows you to read and write data as an array of bytes. As mentioned earlier, we’ll present stream reader and writer classes that allow you to read and write formatted text data or other binary data types to a stream. Using the FileStream object MyFileStream that we created earlier in the chapter, we can begin writing byte-type data to a newly created file. The following code fragment shows how you can write 10 bytes to a file.

 

C#

 

...

byte [ ] MyByteArray = new byte[10];

 

for (int i = 0; i < MyByteArray.Length; i++)

{

    MyByteArray[i] = 1;

}

try

{

    MyFileStream.Write(MyByteArray, 0, MyByteArray.Length);

}

catch (Exception e)

{

    Console.WriteLine("Write failed with error: " + e.Message);

}

...

 

Visual Basic .NET

 

Dim MyByteArray(10) As Byte

Dim i As Short

 

For i = MyByteArray.GetLowerBound(0) To MyByteArray.GetUpperBound(0) - 1

    MyByteArray(i) = i

Next

 

Try

  MyFileStream.Write(MyByteArray, 0, MyByteArray.GetUpperBound(0))

  Console.WriteLine("Write() is OK!")

Catch e As Exception

  Throw New Exception("Write failed with error: " + e.Message)

End Try

 

Once bytes are written to a file, you can continue writing additional bytes or start reading the bytes that are already written. As you write bytes to a file, FileStream maintains a stream Position property that knows where the last byte was written to the stream or read from the stream. The Position property can be manipulated directly by setting it to a value offset position in the file, or you can call the Seek() method to change the position. The following code fragment demonstrates how to set the position to the beginning of the file using the Seek() method on MyFileStream:

 

C#

 

...

try

{

     MyFileStream.Seek(0, SeekOrigin.Begin);

     Console.WriteLine("Seek() is OK");

}

catch (Exception e)

{

     throw new Exception("Seek failed with error: " + e.Message);

}

...

 

Visual Basic .NET

 

...

Try

  MyFileStream.Seek(0, SeekOrigin.Begin)

  Console.WriteLine("Seek() is OK")

 

Catch e As Exception

    Throw New Exception("Seek failed with error: " + e.Message)

 End Try

 ...

 

Once the position is set and there are bytes that follow the position, you can begin reading bytes from the file. Reading bytes is simple because all you have to do is call the FileStream’s Read() method using a byte array to receive a sequence of bytes from where the stream Position is set. When Read() completes successfully, it will return the number of bytes read. It’s important to note that Read() might return less bytes than you requested and the buffer you supply might not be filled. This normally happens when you reach the end of a file stream. When you reach the end of the file stream and try to read more bytes, Read() will return zero. The following code fragment describes how to read a file stream one byte at a time until you reach the end of the file:

 

C#

 

...

byte[ ] MyReadBuffer = new byte[1];

 

while (true)

{

   int BytesRead;

 

    try

    {

       BytesRead = MyFileStream.Read(MyReadBuffer, 0, MyReadBuffer.Length);

       Console.WriteLine("Read() is OK");

     }

     catch (Exception e)

     {

       throw new Exception("Read failed with error: " + e.Message);

     }

 

     if (BytesRead == 0)

     {

       Console.WriteLine("No more bytes to read");

         break;

      }

      Console.WriteLine("Read byte -> " + MyReadBuffer[0].ToString());

      }

...

 

Visual Basic .NET

 

...

Dim MyReadBuffer(1) As Byte

 

While True

   Dim BytesRead As Integer

 

   Try

      BytesRead = MyFileStream.Read(MyReadBuffer, 0, MyReadBuffer.GetUpperBound(0))

      Console.WriteLine("Read() is OK")

 

    Catch e As Exception

        Throw New Exception("Read failed with error: " + e.Message)

    End Try

 

    If BytesRead = 0 Then

        Console.WriteLine("No more bytes to read!")

Exit While

     End If

 

        Console.WriteLine("Read byte -> " + MyReadBuffer(0).ToString())

End While

...

 

When reading and writing data to a FileStream, I/O is buffered, this means that data is read and written to a file in the most efficient manner possible. For example, if your application is designed to write data in small chunks using many Write calls, the data written will be collected to memory flushed to the actual disk mechanism at some point. Later in this chapter, we’ll talk about a composable stream that provides buffering capabilities to make stream I/O more efficient. However, because the FileStream class provides buffering already, there’s no point in using another buffering mechanism above this class.

 

Closing a File

 

When all reading and writing to a file is complete, you should close the FileStream to release operating system resources related to the file being manipulated. To close the FileStream, simply call the Close() method. If you try to read or write to the file after calling Close(), all methods will fail. We demonstrated how to call Close() in the try-catch-finally programming block earlier in this chapter when we showed how to create a file stream.

 

 

C++ Example: Writing and reading text – StreamWriter and StreamReader

 

Create a new CLR console application project and you might want to use TextIOCP as the project and solution names.

 

C++/CLI StreamWriter and StreamReader Console Mode project

 

Add the following code.

 

// TextIOCP.cpp : main project file.

 

#include "stdafx.h"

 

using namespace System;

using namespace System::IO;

 

[STAThread]

int main(array<System::String ^> ^args)

{

           StreamWriter^ MyStreamWriter = nullptr;

           String^ FileName = "C:\\temp\\cricket.txt";

 

            // Let's write a string to a file named cricket.txt

            try

            {

                try

                {

                     MyStreamWriter = gcnew StreamWriter(FileName);

                     Console::WriteLine("StreamWriter() is OK, ready for writing...");

                }

                catch (Exception^ e)

                {

                    throw gcnew Exception("Failed to create a stream writer with error: " + e->Message);

                }

 

                try

                {

                    Console::WriteLine("Writing some text into a {0} file using StreamWriter()...", FileName);

                    MyStreamWriter->WriteLine("Using stream writers is easy!");

                    MyStreamWriter->WriteLine("Using stream readers is also easy!");

                    MyStreamWriter->WriteLine("Yes it is true!");

                    MyStreamWriter->WriteLine("Don\'t believe? Try it yourself!");

                }

                catch (Exception^ e)

                {

                    throw gcnew Exception("Failed to write using a stream writer with error: " + e->Message);

                }

                    Console::WriteLine("Finished writing text to a {0} file...", FileName);

            }

            catch (Exception^ e)

            {

                    Console::WriteLine(e->Message);

            }

            finally

            {

                MyStreamWriter->Close();

                Console::WriteLine("Close() for StreamWriter is OK...");

            }

 

            StreamReader^ MyStreamReader = nullptr;

            String^ FileName1 = "C:\\temp\\cricket.txt";

 

            try

            {

                try

                {

                     MyStreamReader = gcnew StreamReader(FileName1);

                     Console::WriteLine("\nStreamReader() is OK, ready for reading...");

                }

                catch (Exception^ e)

                {

                    throw gcnew Exception("Failed to open stream reader with error: " + e->Message);

                }

 

                String^ FileData = nullptr;

 

                do

                {

                    try

                    {

                        FileData = MyStreamReader->ReadLine();

                        Console::WriteLine("Reading {0}...", FileName1);

                    }

                    catch (Exception^ e)

                    {

                        throw gcnew Exception("Failed to read from stream with error: " + e->Message);

                    }

 

                    if (FileData != nullptr)

                    {

                         Console::WriteLine("We read -> \"{0}\"", FileData);

                    }

                }

                while (FileData != nullptr);

                         Console::WriteLine("Finished reading text from a {0} file.", FileName1);

            }

            catch (Exception^ e)

            {

                         Console::WriteLine(e->Message);

            }

            finally

            {

                MyStreamReader->Close();

                Console::WriteLine("Close() for StreamReader is OK...");

            }

    return 0;

}

 

Build and run the project. The following is the output example when run at the Windows console/command prompt.

 

C++/CLI StreamWriter and StreamReader Console Mode project sample output

 

You can try opening the created text file as shown below.

 

C++/CLI StreamWriter and StreamReader Console Mode project - the generated text file

 

C# Example: Writing and reading text – StreamWriter and StreamReader

 

Create a new console application project. You can use the solution and project name as shown in the following Figure.

 

C# StreamWriter and StreamReader Console Mode application project

 

Add the following code.

 

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

 

// <summary>

// This is a simple sample that demonstrates how to use stream readers and writers to perform IO on a file.

// </summary>

namespace TextIOCS

{

    class Program

    {

        // <summary>

        // The main entry point for the application.

        // </summary>

        [STAThread]

        static void Main(string[] args)

        {

            StreamWriter MyStreamWriter = null;

            // Let's write a string to a file named Jim.txt

            try

            {

                try

                {

                    MyStreamWriter = new StreamWriter(".\\Jim.txt");

                    Console.WriteLine("StreamWriter() is OK, ready for writing");

                }

                catch (Exception e)

                {

                    throw new Exception("Failed to create a stream writer with error: " + e.Message);

                }

 

                try

                {

                    Console.WriteLine("Writing some text into a file using StreamWriter()...");

                    MyStreamWriter.WriteLine("Using stream writers is easy!");

                    MyStreamWriter.WriteLine("Using stream readers is also easy!");

                    MyStreamWriter.WriteLine("Yes it is true!");

                }

                catch (Exception e)

                {

                    throw new Exception("Failed to write using a stream writer with error: " + e.Message);

                }

                Console.WriteLine("Finished writing text to a file");

            }

            catch (Exception e)

            {

                Console.WriteLine(e.Message);

                return;

            }

            finally

            {

                MyStreamWriter.Close();

                Console.WriteLine("Close() is OK");

            }

 

            StreamReader MyStreamReader = null;

 

            try

            {

                try

                {

                    MyStreamReader = new StreamReader(".\\Jim.txt");

                    Console.WriteLine("StreamReader() is OK, ready for reading");

                }

                catch (Exception e)

                {

                    throw new Exception("Failed to open stream reader with error: " + e.Message);

                }

 

                string FileData = null;

 

                do

                {

                    try

                    {

                        FileData = MyStreamReader.ReadLine();

                        Console.WriteLine("Reading...");

                    }

                    catch (Exception e)

                    {

                        throw new Exception("Failed to read from stream with error: " + e.Message);

                    }

 

                    if (FileData != null)

                    {

                        Console.WriteLine("We read -> " + FileData);

                    }

                }

                while (FileData != null);

 

                Console.WriteLine("Finished reading text from a file.");

            }

            catch (Exception e)

            {

                Console.WriteLine(e.Message);

                return;

            }

            finally

            {

                MyStreamReader.Close();

            }

        }

    }

}

 

An output sample:

 

C# StreamWriter and StreamReader Console Mode application project - a sample output

 

 

 


 

< FileStream Examples | Main | BinaryWriter & BinaryReader Examples >