3. The DirectoryInfo and FileInfo Classes
The DirectoryInfo and
FileInfo classes mirror the functionality in the Directory and File
classes. In addition, they make it easy to walk through directory and
file relationships. For example, you can easily retrieve the FileInfo
objects for the files in a directory represented by a DirectoryInfo
object.
Note that while the
Directory and File classes expose only methods, DirectoryInfo and
FileInfo provide a combination of properties and methods. For example,
while the File class had separate GetAttributes() and SetAttributes()
methods, the FileInfo class includes an Attributes property.
Another nice thing
about the DirectoryInfo and FileInfo classes is that they share a common
set of properties and methods because they derive from the common
FileSystemInfo base class. Table 4 describes the members they have in common.
Table 4. DirectoryInfo and FileInfo Members
Member | Description |
---|
Attributes | Allows you to retrieve or set attributes using a combination of values from the FileAttributes enumeration. |
CreationTime, LastAccessTime, and LastWriteTime | Allows you to set or retrieve the creation time, last-access time, and last-write time using a DateTime object. |
Exists | Returns
True or False depending on whether the file or directory exists. In
other words, you can create FileInfo and DirectoryInfo objects that
don't actually correspond to current physical directories, although you
obviously won't be able to use properties such as CreationTime and
methods such as MoveTo(). |
FullName, Name, and Extension | Returns
a string that represents the fully qualified name, the directory or
file name (with extension), or the extension on its own, depending on
which property you use. |
Delete() | Removes
the file or directory, if it exists. When deleting a directory, it must
be empty, or you must specify an optional parameter set to True. |
Refresh() | Updates
the object so it's synchronized with any file system changes that have
happened in the meantime (for example, if an attribute was changed
manually using Windows Explorer). |
Create() | Creates the specified directory or file. |
MoveTo() | Copies
the directory and its contents or the file. For a DirectoryInfo object,
you need to specify the new path; for a FileInfo object, you specify a
path and file name. |
In addition, the FileInfo and DirectoryInfo classes have a few unique members, as indicated in Table 5 and Table 6.
Table 5. Unique DirectoryInfo Members
Member | Description |
Parent and Root | Returns
a DirectoryInfo object that represents the parent or root directory.
For a directory like c:\temp\myfiles, the parent is c:\temp, and the
root is c:\. |
CreateSubdirectory() | Creates
a directory with the specified name in the directory represented by the
DirectoryInfo object. It also returns a new DirectoryInfo object that
represents the subdirectory. |
GetDirectories() | Returns an array of DirectoryInfo objects that represent all the subdirectories contained in this directory. |
GetFiles() | Returns an array of FileInfo objects that represent all the files contained in this directory. |
Table 6. Unique FileInfo Members
Member | Description |
---|
Directory | Returns a DirectoryInfo object that represents the parent directory. |
DirectoryName | Returns a string that identifies the name of the parent directory. |
Length | Returns a Long (64-bit integer) with the file size in bytes. |
CopyTo() | Copies
a file to the new path and file name specified as a parameter. It also
returns a new FileInfo object that represents the new (copied) file. You
can supply an optional additional parameter of True to allow
overwriting. |
When you create a DirectoryInfo or FileInfo object, you specify the full path in the constructor:
Dim myDirectory As New DirectoryInfo("c:\Temp")
Dim myFile As New FileInfo("c:\Temp\readme.txt")
This path may or may not
correspond to a real physical file or directory. If it doesn't, you can
always use the Create() method to create the corresponding file or
directory:
' Define the new directory and file.
Dim myDirectory As New DirectoryInfo("c:\Temp\Test")
Dim myFile As New FileInfo("c:\Temp\Test\readme.txt")
' Now create them. Order here is important.
' You can't create a file in a directory that doesn't exist yet.
myDirectory.Create()
myFile.Create()
4. The DriveInfo Class
The DriveInfo class allows you
to retrieve information about a drive on your computer. Just a few
pieces of information will interest you. Typically, the DriveInfo class
is merely used to retrieve the total amount of used and free space.
Table 7
shows the DriveInfo members. Unlike the FileInfo and DriveInfo classes,
there's no Drive class with instance versions of these methods.
Table 7. DriveInfo Members
Member | Description |
---|
TotalSize | Gets the total size of the drive, in bytes. This includes allocated and free space. |
TotalFreeSpace | Gets the total amount of free space, in bytes. |
AvailableFreeSpace | Gets
the total amount of available free space, in bytes. Available space may
be less than the total free space if you've applied disk quotas
limiting the space the ASP.NET process can use. |
DriveFormat | Returns the name of the file system used on the drive (such as NTFS or FAT32) as a string. |
DriveType | Returns
a value from the DriveType enumeration, which indicates whether the
drive is a Fixed, Network, CDRom, Ram, or Removable drive (or Unknown if
the drive's type cannot be determined). |
IsReady | Returns
whether the drive is ready for reading or writing operations. Removable
drives are considered "not ready" if they don't have any media. For
example, if there's no CD in a CD drive, IsReady will return False. In
this situation, it's not safe to query the other DriveInfo properties.
Fixed drives are always readable. |
Name | Returns the drive letter name of the drive (such as C: or E:). |
VolumeLabel | Gets
or sets the descriptive volume label for the drive. In an
NTFS-formatted drive, the volume label can be up to 32 characters. If
not set, this property returns a null reference (Nothing). |
RootDirectory | Returns a DirectoryInfo object for the root directory in this drive. |
GetDrives() | Retrieves an array of DriveInfo objects, representing all the logical drives on the current computer. |
Attempting to read from a drive
that's not ready (for example, a CD drive that doesn't have a CD in it)
will throw an exception. To avoid this problem, check the
DriveInfo.IsReady property, and attempt to read other properties only if
it returns True.
|
|
5. A Sample File Browser
You can use methods such
as DirectoryInfo.GetFiles() and DirectoryInfo.GetDirectories() to create
a simple file browser. The following example shows you how. Be warned
that, although this code is a good example of how to use the
DirectoryInfo and FileInfo classes, it isn't a good example of security.
Generally, you wouldn't want a user to be able to find out so much
information about the files on your web server.
The sample file browser
program allows the user to see information about any file in any
directory in the current drive, as shown in Figure 2.
The code for the file browser page is as follows:
Public Partial Class FileBrowser
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
Dim startingDir As String = "c:\"
lblCurrentDir.Text = startingDir
ShowFilesIn(startingDir)
ShowDirectoriesIn(startingDir)
End If
End Sub
Private Sub ShowFilesIn(ByVal dir As String)
lblFileInfo.Text = ""
lstFiles.Items.Clear()
Try
Dim dirInfo As New DirectoryInfo(dir)
For Each fileItem As FileInfo In dirInfo.GetFiles()
lstFiles.Items.Add(fileItem.Name)
Next
Catch err As Exception
' Ignore the error and leave the list box empty.
End Try
End Sub
Private Sub ShowDirectoriesIn(ByVal dir As String)
lstDirs.Items.Clear()
Try
Dim dirInfo As New DirectoryInfo(dir)
For Each dirItem As DirectoryInfo In dirInfo.GetDirectories()
lstDirs.Items.Add(dirItem.Name)
Next
Catch err As Exception
' Ignore the error and leave the list box empty.
End Try
End Sub
Protected Sub cmdBrowse_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdBrowse.Click
' Browse to the currently selected subdirectory.
If lstDirs.SelectedIndex <> −1 Then
Dim newDir As String = Path.Combine(lblCurrentDir.Text, _
lstDirs.SelectedItem.Text)
lblCurrentDir.Text = newDir
ShowFilesIn(newDir)
ShowDirectoriesIn(newDir)
End If
End Sub
Protected Sub cmdParent_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdParent.Click
' Browse up to the current directory's parent.
' The Directory.GetParent method helps us out.
Dim newDir As String
If Directory.GetParent(lblCurrentDir.Text) Is Nothing Then
' This is the root directory; there are no more levels.
Exit Sub
Else
newDir = Directory.GetParent(lblCurrentDir.Text).FullName
End If
lblCurrentDir.Text = newDir
ShowFilesIn(newDir)
ShowDirectoriesIn(newDir)
End Sub
Protected Sub cmdShowInfo_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdShowInfo.Click
' Show information for the currently selected file.
If lstFiles.SelectedIndex <> −1 Then
Dim fileName As String = Path.Combine(lblCurrentDir.Text, _
lstFiles.SelectedItem.Text)
Dim displayText As New StringBuilder()
Try
Dim selectedFile As New FileInfo(fileName)
displayText.Append("<b>")
displayText.Append(selectedFile.Name)
displayText.Append("</b><br />Size: ")
displayText.Append(selectedFile.Length)
displayText.Append("<br />")
displayText.Append("Created: ")
displayText.Append(selectedFile.CreationTime.ToString())
displayText.Append("<br />Last Accessed: ")
displayText.Append(selectedFile.LastAccessTime.ToString())
Catch err As Exception
displayText.Append(err.Message)
End Try
lblFileInfo.Text = displayText.ToString()
End If
End Sub
End Class
5.1. Dissecting the Code . . .
The list controls in
this example don't post back immediately. Instead, the web page relies
on the Browse to Selected, Up One Level, and Show Info buttons.
By
default, directory names don't end with a trailing backslash (\)
character (for example, c:\Temp is used instead of c:\Temp\). However,
when referring to the root drive, a slash is required. This is because
of an interesting inconsistency that dates back to the days of DOS. When
using directory names, c:\ refers to the root drive, but c: refers to
the current directory, whatever it may be. This quirk can cause problems
when you're manipulating strings that contain file names, because you
don't want to add an extra trailing slash to a path (as in the invalid
path c:\\myfile.txt). To solve this problem, the page uses the Combine()
method of the Path class. This method correctly joins any file and path
name together, adding the \ when required.
The
code includes all the necessary error handling code. If you attempt to
read the information for a file that you aren't permitted to examine,
the error message is displayed instead of the file details section. If
an error occurs when calling DirectoryInfo.GetFiles() or
DirectoryInfo.GetDirectories(), the error is simply ignored and the
files or subdirectories aren't shown. This error occurs if the account
that's running your code doesn't have permission to read the contents of
the directory. For example, this occurs if you try to access the
c:\System Volume Information directory in Windows and you're not an
administrator.
The
ShowFilesIn() and ShowDirectoriesIn() methods loop through the file and
directory collections to build the lists. Another approach is to use
data binding instead, as shown in the following code sample:
' Another way to fill lstFiles.
Dim dirInfo As New DirectoryInfo(dir)
lstFiles.DataSource = dirInfo.GetFiles()
lstFiles.DataMember = "Name"
lstFiles.DataBind()
Just
remember that when you bind a collection of objects, you need to
specify which property will be used for the list. In this case, it's the
DirectoryInfo.Name or FileInfo.Name property.