You are here: Home > Articles > Article Display

Viewing and editing file and directory attributes in ASP.NET

The System.IO.FileAttributes class gives us access to file/directory attributes. In this article, we'll see how to use this class to first read the current attributes and then change them.

Published: Dec 2, 2002 | Last Edited: Aug 20, 2005
Tested with: ASP.NET 1.1
Category: ASP.NET
26,533 views

Introduction

The System.IO.FileAttributes class gives us access to file/directory attributes. In this article, we'll see how to use this class to first read the current attributes and then change them.

The System.IO.FileAttributes class

The class has numerous members that can be accessed. These members, which are really file or directory properties, fall under the Mscorlib Assembly (in Mscorlib.dll), and should be the same for Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, and the Windows .NET Server family.

Member Name Description
Archive The file's archive status. Applications use this attribute to mark files for backup or removal.
Compressed The file is compressed.
Device Reserved for future use.
Directory The file is a directory.
Encrypted The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and directories.
Hidden The file is hidden, and thus is not included in an ordinary directory listing.
Normal The file is normal and has no other attributes set. This attribute is valid only if used alone.
NotContentIndexed The file will not be indexed by the operating system's content indexing service.
Offline The file is offline. The data of the file is not immediately available.
ReadOnly The file is read-only.
ReparsePoint The file contains a reparse point, which is a block of user-defined data associated with a file or a directory.
SparseFile The file is a sparse file. Sparse files are typically large files whose data are mostly zeros.
System The file is a system file. The file is part of the operating system or is used exclusively by the operating system.
Temporary The file is temporary. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

This enumeration allows a bitwise combination of its member values. Bit fields are generally used for lists of elements that might occur in combination. Therefore, bit fields are designed to be combined with a bitwise OR operation to generate unnamed values. Each member in this class carries a bitwise value with it.

The web form: editAttribs.aspx

Our aspx page will accept a directory or a file through the URL (by HTTP GET). I leave this up to you to perform, as it should be pretty easy to do. Make sure it is a virtual path though, otherwise you will have to modify my code. If it's a file, preceed the path by an F, otherwise if it's a directory, preceed the path by a D.

Example of URL

In the example above, we will display the attributes for a file, located at /images/xefteri.gif. If we wanted to see the attributes of the parent directory of this file (i.e. images), then the URL which we would have had to pass would be http://localhost/editAttribs.aspx?location=D/images.

The final template will look like this:

Example output of the Template

The HTML code that produces this is pretty much straight forward. All the attributes, images and checkboxes in the template are declared as a Web Controls, so that we can programatically set them. The StatusMessage label control will output any exceptions on updating the attributes. Our code-behind source code is simply editAttribs.aspx.vb and the class which we will inherit from is called EditAttribs.

1 <%@ Page Language="vb" src="editAttribs.aspx.vb" inherits="EditAttribs" %>
2 <html>
3 <head>
4     <title>Xefteri - Edit Attributes</title>
5     <style type="text/css">
6     #tblContents {
7         font-family: Verdana;
8         font-size: 70%;
9     }
10     </style>
11 </head>
12 <body bgcolor="#ffffff">
13 <form method="post" ID="setAttribs" runat="server">
14     <asp:Label runat="server" ID="StatusMessage" Visible="False" />
15     <table border="0" cellpadding="2" cellspacing="0">
16         <tr>
17             <td bgcolor="#696969">
18                 <table cellspacing="0" cellpadding="4" border="0" bgcolor="#ffffff" id="tblContents">
19                     <tr>
20                         <td valign="top" align="right"><asp:Image runat="server" ID="imgType" /></td>
21                         <td>&nbsp;</td>
22                     </tr>
23                     <tr>
24                         <td valign="top" align="right"><b>Name:</b></td>
25                         <td valign="top"><asp:Label runat="server" ID="lblName" /></td>
26                     </tr>
27                     <tr>
28                         <td colspan="2"><hr size="1" width="100%" noshade></td>
29                     </tr>
30                     <tr>
31                         <td valign="top" align="right"><b>Virtual Location:</b></td>
32                         <td valign="top"><asp:Label runat="server" ID="lblLocation" /></td>
33                     </tr>
34                     <tr>
35                         <td valign="top" align="right"><b>Physical Location:</b></td>
36                         <td valign="top"><asp:Label runat="server" ID="lblAbsLocation" /></td>
37                     </tr>
38                     <tr>
39                         <td valign="top" align="right"><b>Size:</b></td>
40                         <td valign="top"><asp:Label runat="server" ID="lblSize" /></td>
41                     </tr>
42                     <tr>
43                         <td colspan="2"><hr size="1" width="100%" noshade></td>
44                     </tr>
45                     <tr>
46                         <td valign="top" align="right"><b>Created:</b></td>
47                         <td valign="top"><asp:Label runat="server" ID="lblCreated" /></td>
48                     </tr>
49                     <tr>
50                         <td valign="top" align="right"><b>Last Modified:</b></td>
51                         <td valign="top"><asp:Label runat="server" ID="lblModified" /></td>
52                     </tr>
53                     <tr>
54                         <td valign="top" align="right"><b>Last Accessed:</b></td>
55                         <td valign="top"><asp:Label runat="server" ID="lblLastAccessed" /></td>
56                     </tr>
57                     <tr>
58                         <td colspan="2"><hr size="1" width="100%" noshade></td>
59                     </tr>
60                     <tr>
61                         <td valign="top"><asp:CheckBox runat="server" ID="cbxReadOnly" Text="Read-Only" /></td>
62                         <td valign="top"><asp:CheckBox runat="server" ID="cbxHidden" Text="Hidden" /></td>
63                     </tr>
64                     <tr>
65                         <td colspan="2" valign="top"><asp:CheckBox runat="server" ID="cbxArchive" Text="Ready For Archiving" /></td>
66                     </tr>
67                     <tr>
68                         <td colspan="2" valign="top"><asp:CheckBox runat="server" ID="cbxIndexing" Text="For fast searching, allow Indexing Service to index this" /></td>
69                     </tr>
70                     <tr>
71                         <td colspan="2"><hr size="1" width="100%" noshade></td>
72                     </tr>
73                     <tr>
74                         <td colspan="2" valign="top"><asp:Image runat="server" ID="imgCompressed" />Compressed contents to save disk space</td>
75                     </tr>
76                     <tr>
77                         <td colspan="2" valign="top"><asp:Image runat="server" ID="imgEncrypted" /> Encrypted contents to secure data</td>
78                     </tr>
79                     <tr>
80                         <td colspan="2">&nbsp;</td>
81                     </tr>
82                     <tr>
83                         <td colspan="2" align="center" valign="top"><asp:Button runat="server" ID="btnSetAttribs" Text="Update Attributes" onClick="UpdateAttribs_Click" /></td>
84                     </tr>
85                     <tr>
86                         <td colspan="2">&nbsp;</td>
87                     </tr>
88                 </table>
89             </td>
90         </tr>
91     </table>
92 </form>
93 </body>
94 </html>

The code-behind: editAttribs.aspx.vb

Let's take a look, piece by piece, at the code needed to get this done.

1 Option Explicit on
2 Option Strict on
3
4 Imports System
5 Imports System.IO
6 Imports Microsoft.VisualBasic
7
8 Public Class EditAttribs
9
10     Inherits System.Web.UI.Page
11     
12     'declare variables used throughout the class
13     Dim Private strLocation As String
14     Dim Private strAbsLocation As String
15     Dim Private originalLocation As String
16     Dim Private isFile As Boolean
17     Dim Private intTotalFolders As Integer
18     Dim Private intTotalFiles As Integer
19     Dim Private imgYes As String = "yes.gif"
20     Dim Private imgNo As String = "no.gif"
21     'declare the various Web Controls
22     Protected lblLocation As System.Web.UI.WebControls.Label
23     Protected lblAbsLocation As System.Web.UI.WebControls.Label
24     Protected imgType As System.Web.UI.WebControls.Image
25     Protected lblName As System.Web.UI.WebControls.Label
26     Protected lblSize As System.Web.UI.WebControls.Label
27     Protected lblCreated As System.Web.UI.WebControls.Label
28     Protected lblModified As System.Web.UI.WebControls.Label
29     Protected lblLastAccessed As System.Web.UI.WebControls.Label
30     Protected cbxReadOnly As System.Web.UI.WebControls.CheckBox
31     Protected cbxHidden As System.Web.UI.WebControls.CheckBox
32     Protected cbxIndexing As System.Web.UI.WebControls.CheckBox
33     Protected cbxArchive As System.Web.UI.WebControls.CheckBox
34     Protected imgCompressed As System.Web.UI.WebControls.Image
35     Protected imgEncrypted As System.Web.UI.WebControls.Image
36     Protected StatusMessage As System.Web.UI.WebControls.Label
37
38 ...

Our custom class is called EditAttribs, and it inherits from the System.Web.UI.Page parent class. The first thing we do is dimension our global variables, and then declare our Web Controls which are used in the default.aspx page.

1 ...
2
3     Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
4         Dim objFile As FileInfo
5         Dim objFolder As DirectoryInfo
6         'read the location variable passed in the URL
7         strLocation = Request.Params("location")
8         originalLocation = strLocation
9         If strLocation = "" Then
10             strLocation = "/"
11         End If
12         isFile = strLocation.StartsWith("F")
13         strLocation = Mid(strLocation, 2, Len(strLocation))
14         strAbsLocation = Server.MapPath(strLocation)
15         lblLocation.Text = strLocation
16         lblAbsLocation.Text = strAbsLocation
17         'if we are viewing a file
18         If isFile Then
19             imgType.ImageUrl = "file.gif"
20             imgType.AlternateText = "Type: File"
21             objFile = New FileInfo(strAbsLocation)
22             lblName.Text = objFile.Name
23             lblSize.Text = FormatSize(objFile.Length)
24             lblCreated.Text = FormatDate(objFile.CreationTime)
25             lblModified.Text = FormatDate(objFile.LastWriteTime)
26             lblLastAccessed.Text = FormatDate(objFile.LastWriteTime)
27             If ((CDbl(objFile.Attributes And FileAttributes.ReadOnly)) = FileAttributes.ReadOnly) Then
28                 cbxReadOnly.Checked = True
29             End If
30             If ((CDbl(objFile.Attributes And FileAttributes.Hidden)) = FileAttributes.Hidden) Then
31                 cbxHidden.Checked = True
32             End If
33             If ((CDbl(objFile.Attributes And FileAttributes.NotContentIndexed)) = _
34                 FileAttributes.NotContentIndexed) Then
35                 cbxIndexing.Checked = False
36             Else
37                 cbxIndexing.Checked = True
38             End If
39             If ((CDbl(objFile.Attributes And FileAttributes.Archive)) = FileAttributes.Archive) Then
40                 cbxArchive.Checked = True
41             End If
42             If ((CDbl(objFile.Attributes And FileAttributes.Compressed)) = FileAttributes.Compressed) Then
43                 imgCompressed.ImageUrl = imgYes
44                 imgCompressed.AlternateText = "Compressed"
45             Else
46                 imgCompressed.ImageUrl = imgNo
47                 imgCompressed.AlternateText = "Not Compressed"
48             End If
49             If ((CDbl(objFile.Attributes And FileAttributes.Encrypted)) = FileAttributes.Encrypted) Then
50                 imgEncrypted.ImageUrl = imgYes
51                 imgEncrypted.AlternateText = "Encrypted"
52             Else
53                 imgEncrypted.ImageUrl = imgNo
54                 imgEncrypted.AlternateText = "Not Encrypted"
55             End If
56             'if we are viewing a directory
57         Else
58             imgType.ImageUrl = "directory.gif"
59             imgType.AlternateText = "Type: Folder"
60             objFolder = New DirectoryInfo(strAbsLocation)
61             lblName.Text = objFolder.Name
62             'run recursive method to calculate directory size
63             'and include total number of subdirectories and files
64             lblSize.Text = FormatSize(GetDirectorySize(objFolder.FullName)) " (" + intTotalFolders.ToString() + " folders, " + intTotalFiles.Tostring() + " files)"
65             lblCreated.Text = FormatDate(objFolder.CreationTime)
66             lblModified.Text = FormatDate(objFolder.LastWriteTime)
67             lblLastAccessed.text = FormatDate(objFolder.LastWriteTime)
68             If ((CDbl(objFolder.Attributes And FileAttributes.ReadOnly)) = FileAttributes.ReadOnly) Then
69                 cbxReadOnly.Checked = True
70             End If
71             If ((CDbl(objFolder.Attributes And FileAttributes.Hidden)) = FileAttributes.Hidden) Then
72                 cbxHidden.Checked = True
73             End If
74             If ((CDbl(objFolder.Attributes And FileAttributes.NotContentIndexed)) = _
75                 FileAttributes.NotContentIndexed) Then
76                 cbxIndexing.Checked = False
77             Else
78                 cbxIndexing.Checked = True
79             End If
80             If ((CDbl(objFolder.Attributes And FileAttributes.Archive)) = FileAttributes.Archive) Then
81                 cbxArchive.Checked = True
82             End If
83             If ((CDbl(objFolder.Attributes And FileAttributes.Compressed)) = FileAttributes.Compressed) Then
84                 imgCompressed.ImageUrl = imgYes
85                 imgCompressed.AlternateText = "Compressed"
86             Else
87                 imgCompressed.ImageUrl = imgNo
88                 imgCompressed.AlternateText = "Not Compressed"
89             End If
90             If ((CDbl(objFolder.Attributes And FileAttributes.Encrypted)) = FileAttributes.Encrypted) Then
91                 imgEncrypted.ImageUrl = imgYes
92                 imgEncrypted.AlternateText = "Encrypted"
93             Else
94                 imgEncrypted.ImageUrl = imgNo
95                 imgEncrypted.AlternateText = "Not Encrypted"
96             End If
97         End If
98     End Sub
99
100 ...

The Page_Load() method performs most of the actions. It first reads the location variable passed through the URL, to determine if we are looking at a file or a directory, and what its path is. We use the System.IO.FileInfo class to access the attributes if we are looking at a file, and the System.IO.DirectoryInfo class if it's a directory. The Web Controls' output is the same in both cases, except for the lblSize, which includes the number of subdirectories and files in parenthesis when we are looking at a directory. This closely resembles the Windows OS behavior when viewing a directory's properties.

To determine if an attribute is set, we must convert the bit sum of the attribute into a Double value and compare it with the corresponding FileAttribute value. Let's say for example, that we are trying to establish if the attribute Compressed has been set for a directory. We must convert the value of System.IO.DirectoryInfo.Attributes and System.IO.FileAttributes.Compressed into a Double value, and compare it with System.IO.FileAttributes.Compressed. If they are equal, then the attribute has been set.

1 ...
2
3     Protected Sub UpdateAttribs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
4         Dim fileAttribs As FileAttributes = FileAttributes.Normal
5         If Request.Form("cbxReadOnly") = "on" Then
6             fileAttribs = fileAttribs Or FileAttributes.ReadOnly
7         End If
8         If Request.Form("cbxHidden") = "on" Then
9             fileAttribs = fileAttribs Or FileAttributes.Hidden
10         End If
11         If Request.Form("cbxArchive") = "on" Then
12             fileAttribs = fileAttribs Or FileAttributes.Archive
13         End If
14         If Request.Form("cbxIndexing") <> "on" Then
15             fileAttribs = fileAttribs Or FileAttributes.NotContentIndexed
16         End If
17         Try
18             File.SetAttributes(strAbsLocation, fileAttribs)
19             Server.Transfer("editAttribs.aspx?location=" + originalLocation)
20         Catch exc As Exception
21             StatusMessage.Text = exc.Message
22             StatusMessage.Visible = True
23         End Try
24     End Sub
25
26 ...

The UpdateAttribs_Click() method gets called when we click on the button "Update Attributes" in our aspx page. It checks every checkbox control to see if it was checked or not, and sets the file/directory attributes accordingly. To add the attribute ReadOnly for example, we simply create an instance of the FileAttributes class for the file or directory, and add the attribute to the Normal state using OR. This works the same way for both files and directories.

1 ...
2
3     Private Function FormatDate(ByVal datDate as Date) As String
4         Return String.Format("{0:dddd, MMMM dd yyyy - hh:mm tt}", datDate)
5     End Function
6     
7     Private Function FormatSize(ByVal dblFileSize As Double) As String
8         If dblFileSize < 1024 Then
9             Return String.Format("{0:N0} B", dblFileSize)
10         ElseIf dblFileSize < 1024 * 1024 Then
11             Return String.Format("{0:N2} KB", dblFileSize/1024)
12         ElseIf dblFileSize < 1024 * 1024 * 1024 Then
13             Return String.Format("{0:N2} MB", dblFileSize/(1024*1024))
14         End If
15     End Function
16     
17     Private Function GetDirectorySize(ByVal path As String) As Long
18         Dim lngDirSize As Long = 0
19         Dim objDirInfo As DirectoryInfo = New DirectoryInfo(path)
20         Dim arrChildFiles As Array = objDirInfo.GetFiles()
21         Dim arrSubFolders As Array = objDirInfo.GetDirectories()
22         Dim objChildFile As FileInfo
23         Dim objChildFolder As DirectoryInfo
24         'for each file found under the directory
25         'increment by 1 the number of files found
26         'and add its size to the total size
27         For Each objChildFile in arrChildFiles
28             intTotalFiles = intTotalFiles + 1
29             lngDirSize += objChildFile.Length
30         Next
31         'for each subfolder found
32         'increment by 1 the number of sub-directories found
33         'and call this function recursively
34         For Each objChildFolder in arrSubFolders
35             intTotalFolders = intTotalFolders + 1
36             lngDirSize += GetDirectorySize(objChildFolder.FullName)
37         Next
38         Return lngDirSize
39     End Function
40
41 End Class

These last 3 functions perform some general tasks for us. The FormatDate() and FormatSize() give us a custom output for dates and sizes respectively. The GetDirectorySize() returns the total size of a directory - something that is not provided by the current release of the .NET framework. If you wish, you can take a look at a previous article, which goes into more detail on how to accomplish this. The GetDirectorySize() function also calculates the total number of sub-directories and files found under the directory that we are viewing.

Editing other document properties

There are other properties that are available in a file. These include, among others, the Title, Subject, Author, Category, Keywords & Comments. Microsoft makes available a DLL that can read and change these properties. Since this is outside the scope of this article, you can read more about how to do this from Microsoft or from others who have done this.

Conclusion

We have seen how to view and edit file and directory attributes by using the System.IO.FileAttributes class. We are not limited to these attributes though. We can expand on this if we want to, and also edit the CreationTime, LastAccessTime and LastWriteTime. These last 3 attributes are supported under both the System.IO.FileInfo and System.IO.DirectoryInfo classes, and and they can be set and retrieved.

 



Other articles in this category
  1. Smart headers and footers using ASP.NET User Controls
    December 23, 2002
    Good site usability often means removing links from one page back to itself. In this article we will look at how to create an ASP.NET User Control which will act as a common header to a site. It will automatically know which page we are looking at, and it will remove links to the same page from itself. For example, on this site, if we click on the About us section of the header, it will take you to the page, and it will make that link inactive. That way, we know that we are under that section, and we can't click on it anymore.
  2. Maintaining Sorting while Paging in an ASP.NET Datagrid
    December 18, 2002
    The Datagrid server control offers much control and flexibility in presenting data. Two of the actions that are hard-wired into it are Paging and Sorting. On their own they work great, but not so well together. When you sort a column and then move to a previous or next page, the sorting preference is not maintained. In this article we will see how to maintain both by using the Viewstate object.
  3. How postback works in ASP.NET
    December 10, 2002
    In this article, we will take a closer look at how ASP.NET pages post back to themselves, and how to customize this feature in our web applications.
  4. Copying a directory in ASP.NET
    November 25, 2002
    The System.IO.DirectoryInfo class does not come with a method to copy a directory. In this article, we'll see how to create a method to do that, and then use it in an ASP.NET page.
  5. Creating and consuming a Web Service using Visual Studio .NET
    November 18, 2002
    This article will go through the complete process of how to create a Web Service and then how to consume it in any ASPX page. We'll do this entirely within the Visual Studio.NET. Our Web Service will convert Fahrenheit degrees to Celcius.