Managing the File System


The classes that are used to browse around the file system and perform operations such as moving, copying, and deleting files are shown in Figure 24-1.

image from book
Figure 24-1

The following list explains the function of these classes:

  • System.MarshalByRefObject - Base object class for .NET classes that are remotable; permits marshaling of data between application domains.

  • FileSystemInfo - Base class that represents any file system object.

  • FileInfo and File - These classes represent a file on the file system.

  • DirectoryInfo and Directory - These classes represent a folder on the file system.

  • Path - This class contains static members that you can use to manipulate path names.

  • DriveInfo - This class provides properties and methods that provide information on a selected drive.

Tip 

On Windows, the objects that contain files and are used to organize the file system are termed folders. For example, in the path C:\My Documents\ReadMe.txt, ReadMe.txt is a file and My Documents is a folder. Folder is a very Windows-specific term: on virtually every other operating system the term directory is used in place of folder, and in accordance with Microsoft’s goal to design .NET as a platform-independent technology, the corresponding .NET base classes are called Directory and DirectoryInfo. However, due to the potential for confusion with LDAP directories (as discussed in Chapter 42, “Directory Services”), and because this is a Windows book, we’ll stick to the term folder in this discussion.

NET Classes That Represent Files and Folders

You will notice from the previous list that two classes are used to represent a folder and two classes for a file. Which one of these classes you use depends largely on how many times you need to access that folder or file:

  • Directory and File contain only static methods and are never instantiated. You use these classes by supplying the path to the appropriate file system object whenever you call a member method. If you only want to do one operation on a folder or file, then using these classes is more efficient because it saves the overhead of instantiating a .NET class.

  • DirectoryInfo and FileInfo implement roughly the same public methods as Directory and File, as well as some public properties and constructors, but they are stateful and the members of these classes are not static. You need to instantiate these classes before each instance is associated with a particular folder or file. This means that these classes are more efficient if you’re performing multiple operations using the same object, because they read in the authentication and other information for the appropriate file system object on construction, and then do not need to read that information again no matter how many methods and so on you call against each object (class instance). In comparison, the corresponding stateless classes need to check the details of the file or folder again with every method you call.

In this section, you will be mostly using the FileInfo and DirectoryInfo classes, but it so happens that many (though not all) of the methods called are also implemented by File and Directory (although in those cases these methods require an extra parameter - the path name of the file system object, and a couple of the methods have slightly different names). For example:

  FileInfo myFile = new FileInfo(@"C:\Program Files\My Program\ReadMe.txt"); myFile.CopyTo(@"D:\Copies\ReadMe.txt"); 

has the same effect as:

  File.Copy(@"C:\Program Files\My Program\ReadMe.txt", @"D:\Copies\ReadMe.txt"); 

The first code snippet will take slightly longer to execute, because of the need to instantiate a FileInfo object, myFile, but it leaves myFile ready for you to perform further actions on the same file. By using the second example, there is no need to instantiate an object to copy the file.

You can instantiate a FileInfo or DirectoryInfo class by passing to the constructor a string containing the path to the corresponding file system. You’ve just seen the process for a file. For a folder, the code looks similar:

  DirectoryInfo myFolder = new DirectoryInfo(@"C:\Program Files"); 

If the path represents an object that does not exist, an exception will not be thrown at construction, but will instead be thrown the first time that you call a method that actually requires the corresponding file system object to be there. You can find out whether the object exists and is of the appropriate type by checking the Exists property, which is implemented by both of these classes:

  FileInfo test = new FileInfo(@"C:\Windows"); Console.WriteLine(test.Exists.ToString()); 

Note that for this property to return true, the corresponding file system object must be of the appropriate type. In other words, if you instantiate a FileInfo object supplying the path of a folder, or you instantiate a DirectoryInfo object, giving it the path of a file, Exists will have the value false. On the other hand, most of the properties and methods of these objects will return a value if at all possible - they won’t necessarily throw an exception just because the wrong type of object has been called, unless they are asked to do something that really is impossible. For example, the preceding code snippet might first display false (because C:\Windows is a folder). However, it still displays the time the folder was created because a folder still has that information. But if you tried to open the folder as if it were a file, using the FileInfo.Open() method, you’d get an exception.

After you have established whether the corresponding file system object exists, you can (if you are using the FileInfo or DirectoryInfo class) find out information about it using of the properties in the following table.

Open table as spreadsheet

Name

Description

CreationTime

Time file or folder was created

DirectoryName (FileInfo only)

Full path name of the containing folder

Parent (DirectoryInfo only)

The parent directory of a specified subdirectory

Exists

Whether file or folder exists

Extension

Extension of the file; returns blank for folders

FullName

Full path name of the file or folder

LastAccessTime

Time file or folder was last accessed

LastWriteTime

Time file or folder was last modified

Name

Name of the file or folder

Root (DirectoryInfo only)

The root portion of the path

Length (FileInfo only)

The size of the file in bytes

You can also perform actions on the file system object using the methods in the following table.

Open table as spreadsheet

Name

Purpose

Create()

Creates a folder or empty file of the given name. For a FileInfo this also returns a stream object to let you write to the file. (Streams are cove red later in the chapter.)

Delete()

Deletes the file or folder. For folders there is an option for the Delete to be recursive.

MoveTo()

Moves and/or renames the file or folder.

CopyTo()

(FileInfo only) Copies the file. Note that there is no copy method for folders. If you’re copying complete directory trees you’ll need to individually copy each file and create new folders corresponding to the old folders.

GetDirectories()

(DirectoryInfo only) Returns an array of DirectoryInfo objects representing all folders contained in this folder.

GetFiles()

(DirectoryInfo only) Returns an array of FileInfo objects representing all files contained in this folder.

GetFileSystemInfos()

(DirectoryInfo only) Returns FileInfo and DirectoryInfo objects representing all objects contained in this folder, as an array of FileSystemInfo references.

Note that these tables list the main properties and methods and are not intended to be exhaustive.

Tip 

The preceding tables do not list most of the properties or methods that allow you to write to or read the data in files. This is actually done using stream objects, which are covered later in this chapter. FileInfo also implements a number of methods, Open(), OpenRead(), OpenText(), OpenWrite(), Create(), and CreateText(), that return stream objects for this purpose.

Interestingly, the creation time, last access time, and last write time are all writable:

 // displays the creation time of a file, // then changes it and displays it again FileInfo test = new FileInfo(@"C:\MyFile.txt"); Console.WriteLine(test.Exists.ToString()); Console.WriteLine(test.CreationTime.ToString()); test.CreationTime = new DateTime(2001, 1, 1, 7, 30, 0); Console.WriteLine(test.CreationTime.ToString());

Running this application produces results similar to the following:

 True 2/5/2007 2:59:32 PM 1/1/2001 7:30:00 AM

Being able to manually modify these properties might seem strange at first, but it can be quite useful. For example, if you have a program that effectively modifies a file by simply reading it in, deleting it, and creating a new file with the new contents, you’d probably want to modify the creation date to match the original creation date of the old file.

The Path Class

The Path class is not a class that you would instantiate. Rather, it exposes some static methods that make operations on path names easier. For example, suppose that you want to display the full path name for a file, ReadMe.txt in the folder C:\My Documents. You could find the path to the file using the following code:

  Console.WriteLine(Path.Combine(@"C:\My Documents", "ReadMe.txt")); 

Using the Path class is a lot easier than using separation symbols manually, especially because the Path class is aware of different formats for path names on different operating systems. At the time of writing, Windows is the only operating system supported by .NET. However, if .NET were later ported to Unix, Path would be able to cope with Unix paths, in which /, rather than \, is used as a separator in path names. Path.Combine() is the method of this class that you are likely to use most often, but Path also implements other methods that supply information about the path or the required format for it.

The following section presents an example that illustrates how to browse directories and view the properties of files.

Example: A File Browser

This section presents a sample C# application called FileProperties that presents a simple user interface that allows you to browse around the file system and view the creation time, last access time, last write time, and size of files. (You can download the sample code for this application from the Wrox Web site at www.wrox.com.)

The FileProperties application works like this. You type in the name of a folder or file in the main text box at the top of the window and click the Display button. If you type in the path to a folder, its contents are listed in the list boxes. If you type in the path to a file, its details are displayed in the text boxes at the bottom of the form and the contents of its parent folder are displayed in the list boxes. Figure 24-2 shows the FileProperties sample application in action.

image from book
Figure 24-2

The user can very easily navigate around the file system by clicking any folder in the right-hand list box to move down to that folder or by clicking the Up button to move up to the parent folder. Figure 24-2 shows the contents of the My Documents folder. The user can also select a file by clicking its name in the list box. This displays the file’s properties in the text boxes at the bottom of the application (see Figure 24-3).

image from book
Figure 24-3

Note that if you wanted to, you could also display the creation time, last access time, and last modification time for folders using the DirectoryInfo property. You are going to display these properties only for a selected file to keep things simple.

You create the project as a standard C# Windows application in Visual Studio 2005, and add the various text boxes and the list box from the Windows Forms area of the toolbox. You’ve also renamed the controls with the more intuitive names of textBoxInput, textBoxFolder, buttonDisplay, buttonUp, listBoxFiles, listBoxFolders, textBoxFileName, textBoxCreationTime, textBoxLastAccessTime, textBoxLastWriteTime, and textBoxFileSize.

Next, you need to indicate that you will be using the System.IO namespace:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; 

You need to do this for all the file-system-related examples in this chapter, but this part of the code won’t be explicitly shown in the remaining examples. You then add a member field to the main form:

 partial class Form1 : Form {    private string currentFolderPath; 

currentFolderPath stores the path of the folder whose contents are displayed in the list boxes.

Next, you need to add event handlers for the user-generated events. The possible user inputs are:

  • User clicks the Display button - In this case, you need to figure out whether what the user has typed in the main text box is the path to a file or folder. If it’s a folder, you list the files and sub-folders of this folder in the list boxes. If it is a file, you still do this for the folder containing that file, but you also display the file properties in the lower text boxes.

  • User clicks on a file name in the Files list box - In this case, you display the properties of this file in the lower text boxes.

  • User clicks on a folder name in the Folders list box - In this case, you clear all the controls and then display the contents of this subfolder in the list boxes.

  • User clicks on the Up button - In this case, you clear all the controls and then display the contents of the parent of the currently selected folder.

Before you see the code for the event handlers, here is the code for the methods that do all the work. First, you need to clear the contents of all the controls. This method is fairly self-explanatory:

  protected void ClearAllFields() {    listBoxFolders.Items.Clear();    listBoxFiles.Items.Clear();    textBoxFolder.Text = "";    textBoxFileName.Text = "";    textBoxCreationTime.Text = "";    textBoxLastAccessTime.Text = "";    textBoxLastWriteTime.Text = "";    textBoxFileSize.Text = ""; } 

Next, you define a method, DisplayFileInfo(), that handles the process of displaying the information for a given file in the text boxes. This method takes one parameter, the full path name of the file as a String, and it works by creating a FileInfo object based on this path:

  protected void DisplayFileInfo(string fileFullName) {    FileInfo theFile = new FileInfo(fileFullName);    if (!theFile.Exists)    {       throw new FileNotFoundException("File not found: " + fileFullName);    }    textBoxFileName.Text = theFile.Name;    textBoxCreationTime.Text = theFile.CreationTime.ToLongTimeString();    textBoxLastAccessTime.Text = theFile.LastAccessTime.ToLongDateString();    textBoxLastWriteTime.Text = theFile.LastWriteTime.ToLongDateString();    textBoxFileSize.Text = theFile.Length.ToString() + " bytes"; } 

Note that you take the precaution of throwing an exception if there are any problems locating a file at the specified location. The exception itself will be handled in the calling routine (one of the event handlers). Finally, you define a method, DisplayFolderList(), which displays the contents of a given folder in the two list boxes. The full path name of the folder is passed in as a parameter to this method:

  protected void DisplayFolderList(string folderFullName) {    DirectoryInfo theFolder = new DirectoryInfo(folderFullName);    if (!theFolder.Exists)    {       throw new DirectoryNotFoundException("Folder not found: " + folderFullName);    }    ClearAllFields();    textBoxFolder.Text = theFolder.FullName;    currentFolderPath = theFolder.FullName;    // list all subfolders in folder    foreach(DirectoryInfo nextFolder in theFolder.GetDirectories())       listBoxFolders.Items.Add(nextFolder.Name);    // list all files in folder    foreach(FileInfo nextFile in theFolder.GetFiles())       listBoxFiles.Items.Add(nextFile.Name); } 

Next, you examine the event handlers. The event handler that manages the event that is triggered when the user clicks the Display button is the most complex, because it needs to handle three different possibilities for the text the user enters in the text box. For instance, it could be the path name of a folder, the path name of a file, or neither of these:

  protected void OnDisplayButtonClick(object sender, EventArgs e) {    try    {      string folderPath = textBoxInput.Text;      DirectoryInfo theFolder = new DirectoryInfo(folderPath);      if (theFolder.Exists)      {         DisplayFolderList(theFolder.FullName);         return;      }      FileInfo theFile = new FileInfo(folderPath);      if (theFile.Exists)      {         DisplayFolderList(theFile.Directory.FullName);         int index = listBoxFiles.Items.IndexOf(theFile.Name);         listBoxFiles.SetSelected(index, true);         return;      }      throw new FileNotFoundException("There is no file or folder with "                                       + "this name: " + textBoxInput.Text);    }    catch(Exception ex)    {       MessageBox.Show(ex.Message);    } } 

In this code, you establish if the supplied text represents a folder or file by instantiating DirectoryInfo and FileInfo instances and examining the Exists property of each object. If neither exists, then you throw an exception. If it’s a folder, you call DisplayFolderList() to populate the list boxes. If it’s a file, you need to populate the list boxes and sort out the text boxes that display the file properties. You handle this case by first populating the list boxes. You then programmatically select the appropriate file name in the Files list box. This has exactly the same effect as if the user had selected that item - it raises the item-selected event. You can then simply exit the current event handler, knowing that the selected item event handler will immediately be called to display the file properties.

The following code is the event handler that is called when an item in the Files list box is selected, either by the user or, as indicated previously, programmatically. It simply constructs the full path name of the selected file, and passes this to the DisplayFileInfo() method presented earlier:

  protected void OnListBoxFilesSelected(object sender, EventArgs e) {    try    {      string selectedString = listBoxFiles.SelectedItem.ToString();      string fullFileName = Path.Combine(currentFolderPath, selectedString);      DisplayFileInfo(fullFileName);    }    catch(Exception ex)    {       MessageBox.Show(ex.Message);    } } 

The event handler for the selection of a folder in the Folders list box is implemented in a very similar way, except that in this case you call DisplayFolderList() to update the contents of the list boxes:

  protected void OnListBoxFoldersSelected(object sender, EventArgs e) {    try    {      string selectedString = listBoxFolders.SelectedItem.ToString();      string fullPathName = Path.Combine(currentFolderPath, selectedString);      DisplayFolderList(fullPathName);    }    catch(Exception ex)    {       MessageBox.Show(ex.Message);    } } 

Finally, when the Up button is clicked, DisplayFolderList() must also be called, except that this time you need to obtain the path of the parent of the folder currently being displayed. This is done with the FileInfo.DirectoryName property, which returns the parent folder path:

  protected void OnUpButtonClick(object sender, EventArgs e) {    try    {      string folderPath = new FileInfo(currentFolderPath).DirectoryName;      DisplayFolderList(folderPath);    }    catch(Exception ex)    {       MessageBox.Show(ex.Message);    } } 




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net