January 26, 2021
Hot Topics:

File I/O with Streams - Part 1 - An Excerpt from Inside C#, Second Edition

  • By Tom Archer
  • Send Email »
  • More Articles »

File and FileInfo

In addition to offering a Directory class with only static methods and a DirectoryInfo class with only instance methods, the library offers a File class with only static methods and a FileInfo class with only instance methods. To explore these two classes, we.ll rewrite our example from the "Stream Classes" section that used FileStream, StreamReader, and StreamWriter.first using FileInfo, then using File.

In the first example that follows, we use a FileInfo object and the FileInfo.Create method in place of the overloaded FileStream constructor. Similarly, we later open the same file by using FileInfo.Open in place of the FileStream constructor. When you open a file this way, you must supply the open mode (Append, Create, CreateNew, Open, OpenOrCreate, or Truncate), access permissions (Read, ReadWrite, or Write), and sharing permissions you want to grant to other objects using this file (None, Read, ReadWrite, or Write). As you can see, one advantage of using FileInfo instead of FileStream in this situation is that we can reuse the same FileInfo object.which contains property values such as the filename.and simply regenerate a FileStream object opened in the manner we require:

class FileFileInfoApp
  static void Main(string[] args)
//    Stream s = new FileStream("Bar.txt", FileMode.Create);
      FileInfo f = new FileInfo("Bar.txt");
      FileStream fs = f.Create();

      StreamWriter w = new StreamWriter(fs);
      w.Write("Hello World");

//    s = new FileStream("Bar.txt", FileMode.Open);
      fs = f.Open(FileMode.Open, 
      StreamReader r = new StreamReader(fs);
      string t;
      while ((t = r.ReadLine()) != null)

The equivalent code using the File class static methods is this:

FileInfo f2 = new FileInfo("Bar.txt");
FileStream fs2 = File.Create("Bar.txt");

StreamWriter w2 = new StreamWriter(fs2);
w2.Write("Goodbye Mars");

fs2 = File.Open("Bar.txt", 
                FileAccess.Read, FileShare.None);
StreamReader r2 = new StreamReader(fs2);
while ((t = r2.ReadLine()) != null)

One advantage that the FileInfo and File classes have over the FileStream class in this situation is the OpenText, CreateText, and AppendText methods. These methods will return StreamReader or StreamWriter objects; therefore, we can use them as a kind of shortcut, bypassing the need for a FileStream object:

FileInfo f3 = new FileInfo("Bar.txt");
StreamWriter w3 = f3.CreateText();
w3.Write("Farewell Pluto");

StreamReader r3 = f3.OpenText();
while ((t = r3.ReadLine()) != null)

Parsing Paths

The Path class is designed to enable you to easily perform common operations such as determining whether a filename extension is part of a path and combining two strings into one pathname. A path is a string that provides the location of a file or directory: it doesn't necessarily point to a location on disk. Most members of the Path class don't interact with the file system and don't verify the existence of the file specified by a path string. Path class members that modify a path string have no effect on the names of files in the file system. On the other hand, some of the members of the Path class do validate that a specified path string has the correct form, and they throw an exception if the string contains characters that aren't valid in path strings. All members of the Path class are static and can therefore be called without having an instance of a path. A path can contain absolute or relative location information. Absolute paths fully specify a location: the file or directory can be uniquely identified, regardless of the current location. Relative paths specify a partial location: the current location is used as the starting point when locating a file this way.

The following code illustrates how you might use the Path class to report on various parts of the string that represents the current directory and the name of the current executing module:

using System.Diagnostics;

class TestPathApp
  static void Main(string[] args)
    Process p = Process.GetCurrentProcess();
    ProcessModule pm = p.MainModule;
    string s = pm.ModuleName;


This is the output:



The .NET Framework includes a streams-based I/O subframework that's based on the Stream class and its specialized derivatives. Related classes that support file-based streaming include classes to represent files and directories, with an appropriate range of functionality. We.ve seen how an application can use the streams pattern to stream data between memory buffers, or to persistent storage, with a comprehensive set of options for formatting and encoding the stream. The .NET Framework classes supply two primary stream formatting classes to support both binary and XML-formatted data, as well as a set of character encoding classes. In the second part of this two-part series, we'll cover the topics of Non-console use of streams and serialization.


Download demo projects - 98 Kb

For more information:
Inside Visual C#, Second Edition
By Tom Archer
ISBN: 0735616485
Published by Microsoft Press

Reprinted with Permission.

Page 6 of 6

This article was originally published on March 7, 2003

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date