Wor king with Drives, Directories, and F ilesMany times in your ASP.NET applications, you need to interact with the local file system, reading directory structures, reading and writing t
Trang 1Wor king with Drives, Directories, and F iles
Many times in your ASP.NET applications, you need to interact with the local file system, reading
directory structures, reading and writing to files, or performing many other tasks TheSystem.IO
namespace within the NET Framework makes working with file system directories and files very easy
While working with the classes in theSystem.IOnamespace, keep in mind that because your ASP.NET
applications are executing on the server, the file system you are accessing is the one your Web application
is running on You, of course, cannot use an ASP.NET application to access the end user’s file system
The DriveInfo Class
You can start working with theSystem.IOnamespace at the top of the directory tree by using a great
new addition to the NET 3.5 class libraries, theDriveInfoclass This class supplements the
GetLog-icalDrives()method of theDirectoryclass included in prior versions of the NET Framework It
provides you with extended information on any drive registered with the server’s local file system You
can get information such as the name, type, size, and status of each drive Listing 25-1 shows you how to
create aDriveInfoobject and display local drive information on a Web page
Listing 25-1: Displaying local drive information
VB
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim drive As New System.IO.DriveInfo("C:\") lblDriveName.Text = drive.Name
lblDriveType.Text = drive.DriveType.ToString() lblAvailableFreeSpace.Text = drive.AvailableFreeSpace.ToString() lblDriveFormat.Text = drive.DriveFormat
lblTotalFreeSpace.Text = drive.TotalFreeSpace.ToString() lblTotalSize.Text = drive.TotalSize.ToString()
lblVolumeLabel.Text = drive.VolumeLabel End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Displaying Drive Information</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr><td>Drive Name:</td><td>
<asp:Label ID="lblDriveName" runat="server" Text="Label" />
</td></tr>
<tr><td>Drive Type:</td><td>
<asp:Label ID="lblDriveType" runat="server" Text="Label"/>
</td></tr>
<tr><td>Available Free Space:</td><td>
<asp:Label ID="lblAvailableFreeSpace" runat="server" Text="Label" />
</td></tr>
<tr><td>Drive Format:</td><td>
<asp:Label ID="lblDriveFormat" runat="server" Text="Label" />
Trang 2<tr><td>Total Free Space:</td><td>
<asp:Label ID="lblTotalFreeSpace" runat="server" Text="Label" />
</td></tr>
<tr><td>Total Size:</td><td>
<asp:Label ID="lblTotalSize" runat="server" Text="Label" />
</td></tr>
<tr><td>Volume Label</td><td>
<asp:Label ID="lblVolumeLabel" runat="server" Text="Label" />
</td></tr>
</table>
</div>
</form>
</body>
</html>
C#
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
System.IO.DriveInfo drive = new System.IO.DriveInfo(@"C:\");
lblDriveName.Text = drive.Name;
lblDriveType.Text = drive.DriveType.ToString();
lblAvailableFreeSpace.Text = drive.AvailableFreeSpace.ToString();
lblDriveFormat.Text = drive.DriveFormat;
lblTotalFreeSpace.Text = drive.TotalFreeSpace.ToString();
lblTotalSize.Text = drive.TotalSize.ToString();
lblVolumeLabel.Text = drive.VolumeLabel;
}
</script>
One of the more interesting properties in the sample is theDriveTypeenumeration This read-only enu-meration tells you what the drive type is, for example CD-ROM, Fixed, Ram, or Removable Figure 25-1 shows you what the page looks like when you view it in a browser
Figure 25-1
Trang 3You can also enumerate through all the drives on the local file system by using theDriveInfo’s static
GetDrives()method Listing 25-2 shows an example of enumerating through the local file system drives
and adding each drive as a root node to a TreeView control
Listing 25-2: Enumerating through local file system drives
VB
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If (Not Page.IsPostBack) Then
For Each drive As System.IO.DriveInfo In System.IO.DriveInfo.GetDrives()
Dim node As TreeNode = New TreeNode() node.Value = drive.Name
’ Make sure the drive is ready before we access it
If (drive.IsReady) Then node.Text = drive.Name & _
" - (free space: " & drive.AvailableFreeSpace & ")"
Else node.Text = drive.Name & " - (not ready)"
End If
Me.TreeView1.Nodes.Add(node) Next
End If End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Enumerate Local System Drives</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td style="width: 100px" valign="top">
<asp:TreeView ID="TreeView1" runat="server"></asp:TreeView>
</td>
</tr>
</table>
</div>
</form>
</body>
</html>
C#
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Trang 4if (!Page.IsPostBack) {
foreach (System.IO.DriveInfo drive in System.IO.DriveInfo.GetDrives()) {
TreeNode node = new TreeNode();
node.Value = drive.Name;
//Make sure the drive is ready before we access it
if (drive.IsReady) node.Text = drive.Name +
" - (free space: " + drive.AvailableFreeSpace + ")";
else node.Text = drive.Name + " - (not ready)";
this.TreeView1.Nodes.Add(node);
}
} }
</script>
Notice that, in this sample, the drive object’sIsReadyproperty is a read-only property used to test
whether the drive is accessible If you are enumerating drives, it’s always a good idea to test for this
before attempting to access any of the other drive properties because removable drives and network
drives may not always be available when your code is executed Figure 25-2 shows what the page looks like when viewed in the browser
Figure 25-2
The Directory and DirectoryInfo Classes
Next, you can build on the previous examples and add the capability to browse through the
system’s directory structure TheSystem.IOnamespace contains two classes for working with file system
Trang 5directories, theDirectoryandDirectoryInfoclasses TheDirectoryclass exposes static methods you
can use to create, move, and delete directories TheDirectoryInforepresents a specific directory and
lets you perform many of the same actions as theDirectoryclass on the specific directory Additionally,
it enumerates child directories and files
To continue the example, you can use theGetDirectories()method of theDirectoryInfoclass to
create a recursive method that loops through each system drive directory tree and adds the directories
to a TreeView control to create a small directory browser Listing 25-3 shows how to create a recursive
LoadDirectories()method to walk through the local file system’s directory structure
Listing 25-3: Enumerating file system directories
VB
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
If (Not Page.IsPostBack) Then
For Each drive As System.IO.DriveInfo In System.IO.DriveInfo.GetDrives()
Dim node As TreeNode = New TreeNode() node.Value = drive.Name
If (drive.IsReady) Then node.Text = drive.Name & _
" - (free space: " & drive.AvailableFreeSpace & ")"
LoadDirectories(node, drive.Name) Else
node.Text = drive.Name & " - (not ready)"
End If
Me.TreeView1.Nodes.Add(node) Next
End If
Me.TreeView1.CollapseAll()
End Sub
Private Sub LoadDirectories(ByVal parent As TreeNode, ByVal path As String)
Dim directory As System.IO.DirectoryInfo = _
New System.IO.DirectoryInfo(path)
Try For Each d As System.IO.DirectoryInfo In directory.GetDirectories()
Dim node As TreeNode = New TreeNode(d.Name, d.FullName)
parent.ChildNodes.Add(node)
Continued
Trang 6’Recurse the current directory LoadDirectories(node, d.FullName) Next
Catch ex As System.UnauthorizedAccessException
parent.Text += " (Access Denied)"
Catch ex As System.IO.IOException
parent.Text += " (Unknown Error: " + ex.Message + ")"
End Try
End Sub
</script>
C#
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
foreach (System.IO.DriveInfo drive in System.IO.DriveInfo.GetDrives())
{
TreeNode node = new TreeNode();
node.Value = drive.Name;
if (drive.IsReady)
{
node.Text = drive.Name +
" - (free space: " + drive.AvailableFreeSpace + ")";
LoadDirectories(node, drive.Name);
}
else
node.Text = drive.Name + " - (not ready)";
this.TreeView1.Nodes.Add(node);
}
}
this.TreeView1.CollapseAll();
}
private void LoadDirectories(TreeNode parent, string path)
{
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(path);
try
{
foreach (System.IO.DirectoryInfo d in directory.GetDirectories())
{
TreeNode node = new TreeNode(d.Name, d.FullName);
parent.ChildNodes.Add(node);
Continued
Trang 7//Recurs the current directory LoadDirectories(node, d.FullName);
} } catch (System.UnauthorizedAccessException e) {
parent.Text += " (Access Denied)";
} catch (System.IO.IOException e) {
parent.Text += " (Unknown Error: " + e.Message + ")";
} }
</script>
Figure 25-3 shows what the page should look like in the browser You should now be able to browse the
directory tree, much as you do in Windows Explorer, by opening and closing the TreeView nodes
Figure 25-3 Notice that the example continuously creates new instances of theDirectoryInfoclass each time the
method executes in order to continue to enumerate the directory tree You could also extend this example
by displaying some additional properties as part of the Nodetext, such as theCreationTime
orAttributes
To perform only a specific action, you don’t have to create an instance of theDirectoryInfoclass You
can simply use the static methods exposed by theDirectoryclass These methods allow you to create,
read properties from, and delete a directory Rather than creating an object instance that represents a
specific path and exposes methods that act on that path, the static methods exposed by theDirectory
Trang 8class generally require you to pass the path as a method parameter Listing 25-4 shows how you can use the static methods exposed by theDirectoryclass to create, read properties from, and delete a directory
Remember to be very careful when deleting a folder from your hard drive It is
possible to permanently delete important data from your system or change the
permissions of a resource, which would result in your losing the ability to access
the resource.
Listing 25-4: Working with the static methods of the Directory class
VB
<%@ Import Namespace="System.IO" %>
<script runat="server">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Directory.CreateDirectory("C:\Wrox")
If Directory.Exists("C:\Wrox") Then
Me.Label1.Text = _
Directory.GetCreationTime("C:\Wrox").ToString() Me.Label2.Text = _
Directory.GetLastAccessTime("C:\Wrox").ToString() Me.Label3.Text = _
Directory.GetLastWriteTime("C:\Wrox").ToString() Directory.Delete("C:\Wrox")
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Using Static Methods</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Creation Time:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
Last Access Time:
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label><br />
Last Write Time:
<asp:Label ID="Label3" runat="server" Text="Label"></asp:Label>
</div>
</form>
</body>
</html>
Continued
Trang 9<%@ Import Namespace="System.IO" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Wrox");
if (Directory.Exists(@"C:\Wrox") ) {
this.Label1.Text =
Directory.GetCreationTime(@"C:\Wrox").ToString();
this.Label2.Text =
Directory.GetLastAccessTime(@"C:\Wrox").ToString();
this.Label3.Text =
Directory.GetLastWriteTime(@"C:\Wrox").ToString();
Directory.Delete(@"C:\Wrox");
} }
</script>
When you load this page in the browser, you will see that theCreation Time, Last Access Time, and
Last Write Timeare displayed Additionally, if you open Windows Explorer, you will see that the Wrox
directory has been deleted
Using Relative Paths and Setting and Getting the Current Directory
When an ASP.NET page is executed, the thread used to execute the code that generates the page, by
default, has a current working directory It uses this directory as its base directory if you have specified
relative paths in your application Therefore, if you pass a relative filename into anySystem.IOclass, the
file is assumed to be located in the current working directory
For example, the default working directory for the ASP.NET Development Server is a directory under
your Visual Studio install root If you installed Visual Studio inC:\Program Files, your ASP.NET
Development Server working directory would bec:\Program Files\Microsoft Visual Studio 9.0\
Common7\IDE
You can find the location of your working directory by using theDirectoryclass’s
GetCurrentDirec-tory()method In addition, you can change the current working directory using theDirectoryclass’s
SetCurrentDirectory()method
Listing 25-5 shows you how to set and then display your working directory
Listing 25-5: Setting and displaying the application’s working directory
VB
<%@ Import Namespace="System.IO" %>
<script runat="server">
Trang 10Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Me.Label1.Text = Directory.GetCurrentDirectory() Directory.SetCurrentDirectory("C:\Wrox")
Me.Label2.Text = Directory.GetCurrentDirectory() End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Set and Display the Working Directory</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Old Working Directory:
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
New Working Directory:
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</div>
</form>
</body>
</html>
C#
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.Label1.Text = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(@"C:\Wrox");
this.Label2.Text = Directory.GetCurrentDirectory();
}
</script>
Note that the directory parameter you specify in theSetCurrentDirectory()method must already
exist; otherwise, ASP.NET throws an exception Knowing this, it would probably be a good idea to use theExists()method of theDirectoryclass to make sure the directory you are specifying does, in fact, already exist before you try to change the working directory
When you execute this code, you should see that it displays the original working directory, and then
displays the new working directory after you change it Figure 25-4 shows what the page looks like when executed
File and FileInfo
Now that you can effectively display and browse a directory tree, you can expand the example even fur-ther by displaying the files located in the directory that is currently selected in your TreeView
control
The simplest way to display the files is to bind aFileInfoarray to aGridView This example uses the
GetFiles()method of theDirectoryInfoclass because it returns an array ofFileInfoobjects You
want to use this method because theFileInfoobject enables you to display some properties of each