Home

File Processing: Directories

 

Introduction to Directories

 

Description

A directory is a section of a medium (floppy disc, flash drive, hard drive, CD, DVD, etc) used to delimit a group of files. Because it appears like a "physical" area, it can handle operations not available on a drive and there are differences between both:

  • A drive can contain one or more directories. A directory cannot contain drives (this is some type of exception: a user can create different directories on a drive in computer A, then map each of these directories in another computer. These mapped drives would appear as different drives in computer B, giving the illusion that the directory contain many drives)
  • A directory can contain other directories. A drive cannot really contain other drives
  • A (sub) directory can be moved from one directory to another. This operation is not possible vice-versa since a drive cannot contain another drive
  • A user can easily delete or remove a directory (if she has the right permissions). The equivalent operation for a drive is rather handled by the operating system

 

The similarities of both types are:

  • A computer cannot have two drives with the same drive letter (name). In a drive and at the same level, a directory cannot have two (sub) directories with the same name. That is, two directories cannot have the same name inside of the same parent directory
  • A drive or a directory can be copied (this operation, although possible, is rather complex for a drive; for example, you can copy a whole hard drive from the computer to an external backup hard drive, but some things, for example from the registry, will not be copied)

The VCL Support for Directories

To support directories, the VCL provides a structure named TDirectory. All of the methods of the TDirectory class are static. This means that you will hardl, if ever, need to declare an instance of the TDirectory class in order to use it.

Directory Creation

To create a directory, you can call the CreateDirectoryA() method of the TDirectory class. Its syntax is:

static void __fastcall CreateDirectoryA(System::UnicodeString Path);

When calling this method, pass the complete path as a string. Here is an example of calling this method:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <IOUtils.hpp>

#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDirectoryClick(TObject *Sender)
{
	TDirectory::CreateDirectoryA(L"A:\\Exercise\\Exercise1");
}
//---------------------------------------------------------------------------

When the TDirectory::CreateDirectoryA() method is called:

  1. It first checks the drive.
    If the drive doesn't exist, because this method cannot create a drive, the compiler would throw a EDirectoryNotFoundException exception
     
    EDirectoryNotFoundException
  2. If the drive exists, the compiler moves to the first directory part of the path.
    If the folder doesn't exist, the compiler would create it. If that first directory doesn't exist, this means that the other directory(ies), if any, under the first don't exist. So, the compiler would create it/them
  3. If the first directory exists and if there is no other directory under that directory, the compiler would stop and would not do anything further
  4. If the directory exists and there is a sub-directory specified under it, the compiler would check the existence of that directory.
    If the sub-directory exists, the compiler would not do anything further and would stop.
    If the sub-directory doesn't exist, the compiler would create it
  5. The compiler would repeat step d until the end of the specified path

The TDirectory::CreateDirectoryA() method doesn't return any value. This mean that, if the directory (or directories) is (or are) created succcessfully, you have no way of checking.

To perform the same operation in Microsoft Windows, you can call the CreateDirectory() function. Its syntax is:

BOOL CreateDirectory(LPCTSTR lpPathName,
                     PSECURITY_ATTRIBUTES lpSecurityAttributes);

The first argument is the path to the directory. It would be processed as seen above. The second argument specifies the permissions to apply when the function is called. The permissions are controlled through a SECURITY_ATTRIBUTES object. The SECURITY_ATTRIBUTES structure is defined as follows:

typedef struct _SECURITY_ATTRIBUTES
{
    DWORD nLength;
    LPVOID lpSecurityDescriptor;
    BOOL bInheritHandle;
} SECURITY_ATTRIBUTES,  *PSECURITY_ATTRIBUTES;

If the CreateDirectory() function succeeds in creating the directory (or directories), it returns TRUE. Here is an example of calling this function:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnDirectoryClick(TObject *Sender)
{
    SECURITY_ATTRIBUTES saPermissions;

    saPermissions.nLength = sizeof( SECURITY_ATTRIBUTES);
    saPermissions.lpSecurityDescriptor = NULL;
    saPermissions.bInheritHandle = TRUE;

    if( CreateDirectory("C:\\Exercise\\Exercise1", &saPermissions) == TRUE )
	ShowMessage("The directory was created.");
}
//---------------------------------------------------------------------------

Operations on Directories

 

Checking for a Directory Existence

Before using or creating a directory, you can first check if it exists. This is because, if a directory already exists in the location where you want to create it, you would be prevented from creating one with the same name. In the same way, if you just decide to directly use a directory that doesn't exist, the operation you want to perform may fail because the directory would not be found.

To check whether a directory exists or not, you can call the TDirectory::Exists() Boolean static method. Its syntax is:

static bool __fastcall Exists(System::UnicodeString Path);

This method receives the (complete) path of the directory. If the path exists, the method returns true. If the directory doesn't exist, the method returns false.

Deleting a Directory

To get rid of a directory, you can call the Delete() method of the TDirectory class. It is overloaded with two versions. One of the versions uses the following syntax;

public static void Delete(string path);

When calling this method, pass the complete path as argument. If the path exists, the method would delete it. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnDeleteClick(TObject *Sender)
{
	if( TDirectory::Exists(L"C:\\Exercise\\Exercise1") )
		TDirectory::Delete(L"C:\\Exercise\\Exercise1");
}
//---------------------------------------------------------------------------

The other version uses the following syntax:

static void __fastcall Delete(System::UnicodeString Path, bool Recursive);

This time, the second argument allows you to specifies whether you want the sub-folders and their contents to be deleted also.

Renaming a Directory

To rename a directory, you can call the Move() method of the TDirectory class. Its syntax is:

static void __fastcall Move(System::UnicodeString SourceDirName,
                            System::UnicodeString DestDirName);

The first argument is the name and path of the directory you want to rename. To rename a directory, provide the same first part for the second argument. Change only the last that involves the actual directory to rename. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnDeleteClick(TObject *Sender)
{
	if( TDirectory::Exists(L"C:\\Exercise\\Exercise1") )
		TDirectory::Move(L"C:\\Exercise\\Exercise1",
				 L"C:\\Exercise10\\Exercise2");
}
//---------------------------------------------------------------------------

When this method is called, the compiler will check whether a folder named Exercise exists on the C:\ drive and it contains a sub-folder named Exercise1. If that folder and that sub-folder exists, it would be renamed.

Moving a Directory

If you want to move a directory, you can also call the Move() method of the TDirectory class. Pass the second argument as the complete and path for the new location:

  • If you want to move a sub-directory from one parent directory to another parent directory, in the second argument, change only the directory (or directories) before the name of the sub-directory and keep the same name for the sub-directory
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDirectoryClick(TObject *Sender)
{
	if( TDirectory::Exists(L"C:\\Exercise1\\Exercise") )
		TDirectory::Move(L"C:\\Exercise1\\Exercise",
				 L"C:\\Exercise2\\Exercise");
}
//---------------------------------------------------------------------------
  • If you want to move a sub-directory from a parent directory to another but with a new name at the new location, use a different path in both arguments

Listing the Files of a Directory

One of the most routine operations performed in a directory consists of looking for a file. Microsoft Windows operating systems and the user's intuition have different ways of addressing this issue. To help you get the files inside a directory, the TDirectory class is equipped with a method named GetFiles(), which is overloaded with many versions. One (the simplest) of the versions uses the following syntax:

static System::DynamicArray<System::UnicodeString>
            __fastcall GetFiles(System::UnicodeString Path);

Directories and File Related Operations

 

The Files of a Directory

To get the files stored inside a directory, you can call the GetFiles() method of the TDirectory class. This method is overloaded with various versions. One of the versions uses the following syntax:

static System::DynamicArray<System::UnicodeString>
	__fastcall GetFiles(System::UnicodeString Path);

Here is an example of callig it:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnFilesClick(TObject *Sender)
{
	TStringDynArray Files = TDirectory::GetFiles(L"C:\\Exercise1");

	for(int i = 0; i < Files.Length; i++)
		ShowMessage(Files[i]);
}
//---------------------------------------------------------------------------

Other versions of the TDirectory::GetFiles() allow you to specify a criterion by which the files must be filtered.

Finding a File in a Directory

Both the VCL and the Win32 library allow you to look for a file. To visually look for a file, you can use the Search window. To display it, you can call the SHFindFile() function. This function is defined in the Shlobj.h. The syntax of this function is:

BOOL SHFindFiles(
  __in_opt  PCIDLIST_ABSOLUTE pidlFolder,
  __in_opt  PCIDLIST_ABSOLUTE pidlSaveFile
);

Here is an example:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <shlobj.h>

#pragma hdrstop

#include "Exercise.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDriveClick(TObject *Sender)
{
    SHFindFiles(NULL, NULL);
}
//---------------------------------------------------------------------------

When this function is called with NULL arguments, its displays blank window with an empty combo box:

Search

To perform a search, the user can click in the combo box and start typing.

 
 
 

Home Copyright © 2010-2011 FunctionX, Inc.