Accessing Files and Directories

Mark Strawmyer Presents: .NET Nuts & Bolts


Welcome to the next installment of the .NET Nuts & Bolts column. In this column we'll explore interacting with files from within .NET. The topics covered will include how to get the properties on files in a directory. It will involve using classes in the System.IO namespace.

Working with Streams

No, I haven't turned this into an article about the great outdoors. Streams have their place with computers as well, although I wouldn't recommend getting your computer near one of the traditional kind. Streams are a concept that have been around for a while, but that are new to Microsoft developers via .NET. A stream is a base class used to abstract the specifics of input and output from the underlying device(s). In general, streams support the ability to read or write. Some streams provide additional capabilities such as seek, which allows navigation forward to a specific location. The device could be a physical file, memory, or the network. List of classes that inherit from the Stream base class are as follows:

  • FileStream—read, write, open, and close files
  • MemoryStream—read and write managed memory
  • NetworkStream—read and write between network connections (System.Net namespace)
  • CryptoStream—read and write data through cryptographic transformations
  • BufferedStream—adds buffering to another stream that does not inherently support buffering

While the streams are used to abstract the input and output from the device, the stream itself is not directly used to read and write data. Instead, a reader or writer object is used to interact with the stream and perform the physical read and write. Here is a list of classes used for reading and writing to streams:

  • BinaryReader and BinaryWriter—read and write binary data to streams
  • StreamReader and StreamWriter—read and write characters from streams
  • StringReader and StringWriter—read and write characters from Strings
  • TextReader and TextWriter—read and write Unicode text from streams

Reading and Writing Text

The following section will use StreamWriter, StreamReader, and FileStream to write text to a file and then read and display the entire contents of the file.

Sample Code to Write and Read a File

using System;
using System.IO;

namespace CodeGuru.FileOperations
{
  /// <remarks>
  /// Sample to demonstrate writing and reading a file.
  /// </remarks>
  class WriteReadFile
  {
   /// <summary>
   /// The main entry point for the application.
   /// </summary>
   [STAThread]
   static void Main(string[] args)
   {
     FileStream fileStream = null;
     StreamReader reader = null;
     StreamWriter writer = null;

     try
     {
      // Create or open the file
      fileStream = new FileStream("c:\\mylog.txt",
         FileMode.OpenOrCreate,
         FileAccess.Write);
      writer = new StreamWriter(fileStream);

      // Set the file pointer to the end of the file
      writer.BaseStream.Seek(0, SeekOrigin.End);

      // Force the write to the underlying file and close
      writer.WriteLine(
          System.DateTime.Now.ToString() + " - Hello World!");
      writer.Flush();
      writer.Close();

      // Read and display the contents of the file one
      // line at a time.
      String fileLine;
      reader = new StreamReader("c:\\mylog.txt");
      while( (fileLine = reader.ReadLine()) != null ) 
      {
        Console.WriteLine(fileLine);
      }
     }
     finally
     {
      // Make sure we cleanup after ourselves
      if( writer != null ) writer.Close();
      if( reader != null ) reader.Close();
     }
   }
  }
}

Working with Directories

There two classes for the manipulation of directories. The classes are named Directory and the DirectoryInfo. The Directory class provides static methods for directory manipulation. The DirectoryInfo class provides instance methods for directory manipulation. They provide the same features and functionality, so the choice comes down to whether you need an instance of an object or not. The members include, but are not limited to the following:

  • Create—create a directory
  • Delete—delete a directory
  • GetDirectories—return subdirectories of the current directory
  • MoveTo—move a directory to a new location

Sample Code to Produce a List of All Directories

The following sample code demonstrates the ability to produce a list of directories using recursion. A recursive procedure is one that calls itself. You must ensure that your procedure does not call itself indefinitely; otherwise, you'll eventually run out of memory. In this case, there are a finite number of subdirectories, so there is automatically a termination point.

using System;
using System.IO;

namespace CodeGuru.FileOperations
{
  /// <remarks>
  /// Sample to demonstrate reading the contents of directories.
  /// </remarks>
  class ReadDirectory
  {
   /// <summary>
   /// The main entry point for the application.
   /// </summary>
   [STAThread]
   static void Main(string[] args)
   {
     DirectoryInfo dirInfo = new DirectoryInfo("c:\\");
     Console.WriteLine("Root: {0}", dirInfo.Name);
     ReadDirectory.ProduceListing(dirInfo, "  ");
     Console.ReadLine();
   }

   /*
    * Recursively produce a list of files
    */
   private static void ProduceListing(DirectoryInfo dirInfo, 
                                      string Spacer)
   {
     Console.WriteLine(Spacer + "{0}", dirInfo.Name);
     foreach(DirectoryInfo subDir in dirInfo.GetDirectories())
     {
      Console.WriteLine(Spacer + Spacer + "{0}", subDir.Name);
      if( subDir.GetDirectories().Length > 0 )
      {
        ProduceListing(subDir, Spacer + "  ");
      }
     }
   }
  }
}

Getting File Properties for Office Documents

Microsoft has an ActiveX component that can be used to programmatically retrieve the summary properties (title, subject, etc.) for files such as Excel, Word, and PowerPoint. It has advantages because it does not use Office Automation so Microsoft Office does not have to be installed. This component can be used to produce a listing of files and their properties.

Sample Code to Produce File Listing with Properties

The following code will populate a DataTable with a list of files and their properties. The DataTable could be bound to a DataGrid or another display control as desired. Be sure you've added the appropriate reference to the dsofile.dll that exposes the file properties. Because this is a COM-based DLL, COM Interop will be used to interact with the DLL.

// Setup the data table
DataTable fileTable = new DataTable("Files");
DataRow fileRow;
fileTable.Columns.Add("Name");
fileTable.Columns.Add("Title");
fileTable.Columns.Add("Subject");
fileTable.Columns.Add("Description");

// Open the directory
DirectoryInfo docDir = new DirectoryInfo("C:\\My Documents\\");
if( !docDir.Exists )
{
  docDir.Create();
}

// Add the document info into the table
DSOleFile.PropertyReader propReader =
       new DSOleFile.PropertyReaderClass();
DSOleFile.DocumentProperties docProps;

foreach(FileInfo file in docDir.GetFiles())
{
  try
  {
   fileRow = fileTable.NewRow();
   docProps = propReader.GetDocumentProperties(file.FullName);
   fileRow["Name"] = file.Name;
   fileRow["Title"] = docProps.Title;
   fileRow["Subject"] = docProps.Subject;
   fileRow["Description"] = docProps.Comments;
   fileTable.Rows.Add(fileRow);
  }
  catch( Exception exception )
  {
   Console.WriteLine("Error occurred: " + exception.Message);
  }
}
propReader = null;
this.DocumentGrid.DataSource = fileTable;
this.DocumentGrid.DataBind();

// Force cleanup so dsofile doesn't keep files locked open
GC.Collect();

Summary

You now have seen several cursory ways in which the System.IO namespace can be used to interact with files and directories. We took an additional look to see how to use the dsofile additional DLL from Microsoft to show the properties for Microsoft Office documents.

Future Columns

If you have something in particular that you would like to see explained here, you can reach me at mstrawmyer@crowechizek.com.

About the Author

Mark Strawmyer, MCSD, MCSE (NT4/W2K), MCDBA is a Senior Architect of .NET applications for large- and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in architecture, design, and development of Microsoft-based solutions. You can reach Mark at mstrawmyer@crowechizek.com.

# # #



About the Author

Mark Strawmyer

Mark Strawmyer is a Senior Architect of .NET applications for large and mid-size organizations. He specializes in architecture, design and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fifth year in a row. You can reach Mark at mark.strawmyer@crowehorwath.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • This paper introduces IBM Java on the IBM PowerLinux 7R2 server and describes IBM's implementation of the Java platform, which includes IBM's Java Virtual Machine and development toolkit.

  • Targeted attacks and advanced threats are customized to infiltrate your unique IT infrastructure, evade conventional defenses, and remain hidden while stealing your corporate data. To detect these criminal intrusions, analysts and security experts agree that organizations should deploy advanced threat protection as part of an expanded security monitoring strategy. For this comparative analysis of breach detection systems, product analysis reports and comparative analysis reports are used to create the security …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds