By Chandra Hundigam
Introduction
This article is focused on understanding the Directory class of System.IO
namespace. The Directory class exposes routines for manipulating directories &
subdirectories. It contains all kinds of routines like creating, moving, and
enumerating through directories and subdirectories. In most of the application
developments we require some file accesses or directory accesses normally we use
some low-level system API like Directory-Control Routines in C (ex:- _mkdir,
_chdir, _rmdir) or Platform SDK function of Kernel32.lib (ex:-
CreateDirectory(),SetCurrentDirectory(),RemoveDirectory()). In .net we have
System.IO.Directory class to do all directory manipulation. For better
understanding I will compare code with some C & SDK programs. You will see how
easy it is in C# when compared to old programming languages.
Let take a small example to get all the available drive information (this includes both
physical & logical drives).
Using C routines
-----------------
#include
#include
#include
#include
#include
void main( void )
{
int drive, curdrive;
static char path[_MAX_PATH];
/* Save current drive. */
curdrive = _getdrive();
printf( "Using C routines, Available drives
are: \n" );
/* If we can switch to the drive, it exists. */
for( drive = 1; drive <= 26; drive++ )
if( !_chdrive( drive ) )
printf( "%c: \n", drive + 'A' - 1 );
}
Output:
Using C routines, Available drives are:
A:\
C:\
D:\
E:\
Z:\
Using Platform SDK File I/O routines
-----------------------------------
#include
#include
void main( void )
{
char *lpBuffer=new char[1000];
long retSize;
retSize=GetLogicalDriveStrings(1000,lpBuffer
);
printf("Using SDK routines, Available drives
are:\n");
for(int i=0;i<=retSize;i++)
{
if(lpBuffer[i]!='\0')
printf("%c",lpBuffer[i]);
else
printf("\n");
}
}
Output:
Using SDK routines, Available drives are:
A:\
C:\
D:\
E:\
Z:\
The same program we will do in C#
GetDr.cs
using System;
using System.IO;
class getDr
{
public static void Main()
{
try
{
string[] str=Directory.GetLogicalDrives();
Console.WriteLine( "Using C# Directory Class ,Available drives are:");
for(int i=0;i< str.Length;i++)
Console.WriteLine(str[i]);
}catch(IOException e) { Console.WriteLine(e.ToString()); }
} // end of Main
}//end of Class
Output:
Using C# Directory Class, Available drives are:
A:\
C:\
D:\
E:\
Z:\
So lets understand how this works System.IO.Directory class has method called
GetLogicalDrives() this method returns all available drives in your system as array of
strings. Before that some important thing to remember is all methods of the
Directory class are static and can therefore be called without having an instance of
a directory. The static methods of the Directory class do a security check on all
methods. If you are going to reuse an object several times, consider using the
corresponding instance method of DirectoryInfo instead, because the security
check will not always be necessary.
Now that we know about Directory class so we will examine the IL code of C#
sample (getDr.exe) and also System.IO library.
(IL code of sample code getDr.exe)
IL_0000:call string[] ['mscorlib']'System.IO'.'Directory'::'GetLogicalDrives'()
|
V
(IL code of System.IO library)
IL_000b: call int32 Microsoft.Win32.Win32Native::GetLogicalDrives()
|
V
(IL code of System.IO library)
.method assembly hidebysig static pinvokeimpl("kernel32.dll" lasterr winapi)
int32 GetLogicalDrives() cil managed preservesig
{ }
If you see the above IL code of System.IO library it internally calls the kernel32.dll
GetLogicalDrives() which is nothing but File I/O function in Kernel32.dll library
which retrieves a bitmask representing the currently available disk drives. When you
call Directory Class methods of System.IO library it internally pinvokes the
Microsoft Win32 native functions (see the above Platform SDK code).
Similarly we will see a sample code to create and change directory. For this sample
code we will be using Directory.CreateDirectory(), Directory.GetCurrentDirectory()
,Directory.Delete(), Directory.Exists() and Directory.SetCurrentDirectory().
chgDr.cs
using System;
using System.IO;
class chgDr
{
public static void Main()
{
try
{
Console.WriteLine("-->Your Current Directory");
String curDir=Directory.GetCurrentDirectory();
Console.WriteLine(curDir);
String newDir="TestDir";
Directory.CreateDirectory(newDir);
Console.WriteLine("--> '" + newDir + "' Directory created");
Directory.SetCurrentDirectory(newDir);
Console.WriteLine("--> Changing to '" + newDir + "' Directory ");
Console.WriteLine(Directory.GetCurrentDirectory());
Console.WriteLine("--> Changing to '" + curDir + "' Directory ");
Directory.SetCurrentDirectory(curDir);
Console.WriteLine(Directory.GetCurrentDirectory());
Console.WriteLine("--> Deleting '" + newDir + "' Directory ");
if(Directory.Exists(newDir))
Directory.Delete(newDir);
Console.WriteLine("--> Checking '" + newDir + "' Directory Exists or not");
if(!Directory.Exists(newDir))
Console.WriteLine("'" + newDir + "' Does not exists ");
}catch(IOException e){ Console.WriteLine(e.ToString()); }
}
}
Output:
D:\samples\vstudio>chgDr
-->Your Current Directory
D:\samples\vstudio
--> 'TestDir' Directory created
--> Changing to 'TestDir' Directory
D:\samples\vstudio\TestDir
--> Changing to 'D:\samples\vstudio' Directory
D:\samples\vstudio
--> Deleting 'TestDir' Directory
--> Checking 'TestDir' Directory Exists or not
'TestDir' Does not exists
Some points to remember:
a) Path names are limited to 248 characters
b) The specified path can also refer to a relative path or a Universal Naming
Convention (UNC) path for a server and share name.
c) Ensure that your paths are well-formed when using methods that accept a
path string .In C# path names should have \\ instead of single \
d) If you don't have permission it will generate FileIOPermission exception.
Further reading
1. .Net More information on .Net technologies