Working with Drives and Directories
On a Windows computer, persistent storage—in other words, disk
drives—is organized into directories (also called
folders). Each drive has a single root directory. The root directory
may have one or more subdirectories. Those subdirectories may in turn have their
own subdirectories, and so on. Network sharing introduces additional complexity.
You can refer to shared network drives and directories by using their share name
(for example, \\MainServer\MyFolder) or a mapped drive letter. Following are
some of the tasks related to drives and directories that you may need to perform
in your .NET programs:
- Determining what drives exist
- Determining whether a specific directory exists
- Creating, moving, and deleting directories
- Setting the current directory
The .NET Framework provides two classes for performing these tasks. The
Directory class exposes static (shared) methods for working with directories,
whereas the DirectoryInfo class provides instance methods. (This is the same as
the distinction between the FileInfo and File classes.) Both classes are part of
the System.IO namespace.
Because the file system treats a directory as a special kind of file, many
class members that are available in the File and FileInfo classes are also
present in the Directory and DirectoryInfo classes. Specifically, FileInfo
members that are also present in DirectoryInfo are as follows:
- CreationTime
- Delete
- LastAccessTime
- LastWriteTime
- MoveTo
The DirectoryInfo class constructor takes as its one argument a string that
specifies the target directory. Here’s the syntax:
New(path)
where path is a string giving the path of the directory. An
exception will be thrown if the directory doesn’t exist, if the path
string isn’t properly formed, if the user doesn’t have the required
permission, or if the path is longer than 256 characters. Here’s an
example of creating an instance of this class:
Dim d As New DirectoryInfo("c:\documents")The Directory and File classes also have some members in common:
- Delete
- GetCreationTime
- GetLastAccessTime
- GetLastWriteTime
- Move
Table 2 shows some additional members of the Directory class; Table 3
describes additional members of the DirectoryInfo class.
Table 2 Additional members of the Directory class.
Class Member
|
Description
|
CreateDirectory(path)
|
Creates the specified directory and, if necessary, the path to it. Returns a type DirectoryInfo for the new directory.
|
GetCurrentDirectory()
|
Returns a type String containing the path of the current working directory.
|
GetDirectories(path)
|
Returns, in an array of type String, the names of all subdirectories in the directory specified by path.
|
GetDirectoryRoot(path)
|
Returns the volume and root information for the specified directory (for example, "c:\").
|
GetFiles(path)
|
Returns, in an array of type String, the names of all files in the specified directory.
|
GetFileSystemEntries(path)
|
Returns, in an array of type String, the names of all files and subdirectories in the specified directory.
|
GetLogicalDrives()
|
Returns, in an array of type String, all the logical drives on the system, in the form "<drive letter>:\".
|
GetParent(path)
|
Returns a type DirectoryInfo referencing the parent of the specified directory).
|
SetCurrentDirectory(path)
|
Sets the application’s working directory to the specified directory.
|
Table 3 Additional members of the DirectoryInfo class.
Class Member
|
Description
|
Parent
|
Returns a type DirectoryInfo referring to the parent directory of the instance directory.
|
Root
|
Returns a type DirectoryInfo referring to the root directory.
|
CreateSubdirectory(path)
|
Creates the subdirectory specified by path and returns a type DirectoryInfo referring to the new directory.
|
GetDirectories()
|
Returns an array of type DirectoryInfo containing references to all of the subdirectories in the instance directory.
|
GetFiles()
|
Returns an array of type FileInfo containing references to all of the files in the instance directory.
|
Notice that the Directory class has methods for getting and setting the
current working directory. What exactly is this?
Any running application has a working directory, which is where the
application’s file operations (such as opening a file) will occur by
default—that is, if no path is specified for the operation. The working
directory is also the location from which relative path specifications are
determined. During program development in Visual Studio, the working directory
is by default the bin directory within the project directory. After deployment,
it’s the directory where the application’s .exe file is located.
It’s rarely a good idea to rely on the default working directory, however,
so your code should either change the working directory or always specify the
complete path for file operations.
Let’s wrap up this article with some examples of using the Directory
and DirectoryInfo classes.
The following code uses the Directory class to display, in the immediate
window, a list of all subdirectories in the c:\documents directory:
Dim sa() As String
Dim s As String
sa = Directory.GetDirectories("c:\documents")
For Each s In sa
Debug.WriteLine(s)
Next
This code performs the same task, but uses the DirectoryInfo class:
Dim d As New DirectoryInfo("c:\documents")
Dim da() As DirectoryInfo
Dim x As DirectoryInfo
da = d.GetDirectories
For Each x In da
Debug.WriteLine(x.FullName)
NextThe next example checks to see whether a specified directory exists. If so, a
message to that effect is displayed. If not, the directory is created.
Const DIR_PATH = "c:\my_new_documents"
If Directory.Exists(DIR_PATH) Then
MsgBox(DIR_PATH & " already exists.")
Else
Directory.CreateDirectory(DIR_PATH)
MsgBox(DIR_PATH & " created successfully.")
End If
For a final demonstration, I’ll show you how to determine the total
number of files in a directory and all of its subdirectories, along with their
total size (see Listing 1). The program makes use of a powerful technique called
recursion, whereby a function calls itself repeatedly to carry out a
repetitive task. Here’s how it works. The function, called
FilesInDirectory(), is passed a type DirectoryInfo referencing the directory of
interest. Code in the function obtains a list of all files in that directory and
gets the count and total size of these files, adding them to a summary
(maintained in a structure that’s defined in the code). Then the code gets
a list of all subdirectories that the current directory contains, and calls
itself for each one. As a result the code "worms" its way down through
all levels of subdirectories, and gets the file information for each one.
Recursion is not used all that often, but in appropriate situations it’s a
very powerful programming technique.
Listing 1 Using recursion to list files and their sizes.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim result As FileSummary
Dim msg As String
result = FilesInDirectory(New DirectoryInfo("c:\documents"))
msg = "The directory and its subdirectories contain "
msg &= result.Count.ToString & " files totaling "
msg &= result.TotalSize.ToString & " bytes."
MsgBox(msg)
End Sub
Private Function FilesInDirectory(ByVal d As DirectoryInfo) As FileSummary
’ Returns the total number and total size of files in d
’ and all of its subdirectories.
Dim fs1 As New FileSummary()
Dim fs2 As New FileSummary()
Dim fa() As FileInfo
Dim f As FileInfo
’ Get the files in this directory.
fa = d.GetFiles
’ Add their info to the summary.
For Each f In fa
fs1.Count += 1
fs1.TotalSize += f.Length
Next
’ Now do the same for all the subdirectories.
Dim da() As DirectoryInfo
Dim d1 As DirectoryInfo
da = d.GetDirectories
For Each d1 In da
fs2 = FilesInDirectory(d1)
fs1.Count += fs2.Count
fs1.TotalSize += fs2.TotalSize
Next
’ Return the current totals.
Return fs1
End Function
Structure FileSummary
Public TotalSize As Long
Public Count As Integer
End Structure
Make a New Comment
You must login in order to post a comment.