Finding a File

From RAD Studio
Jump to: navigation, search

Go Up to Manipulating Files

There are three routines used for finding a file:

  • FindFirst searches for the first instance of a filename with a given set of attributes in a specified directory.
  • FindNext returns the next entry matching the name and attributes specified in a previous call to FindFirst.
  • FindClose releases memory allocated by FindFirst. You should always use FindClose to terminate a FindFirst/FindNext sequence.
    • If you want to know if a file exists, the FileExists function returns true if the file exists, false otherwise.

The three file find routines take a TSearchRec as one of the parameters. TSearchRec defines the file information searched for by FindFirst or FindNext. The declaration for TSearchRec is:

Delphi:

 type
   TFileName = string;
   TSearchRec = record
     Time: Integer;//Time contains the time stamp of the file.
     Size: Integer;//Size contains the size of the file in bytes.
     Attr: Integer;//Attr represents the file attributes of the file.
     Name: TFileName;//Name contains the filename and extension.
     ExcludeAttr: Integer;
     FindHandle: THandle;
     FindData: TWin32FindData;//FindData contains additional information such as
     //file creation time, last access time, long and short filenames.
   end;

C++:

struct TSearchRec
{
    int Time; // time stamp of the file
    int Size; // size of the file in bytes
    int Attr; // file attribute flags 
    AnsiString Name; // filename and extension
    int ExcludeAttr; // file attribute flags for files to ignore
    unsigned FindHandle;
    _WIN32_FIND_DATAA FindData; // structure with addition information
};

If a file is found, the fields of the TSearchRec type parameter are modified to describe the found file. One field of TSearchRec that is of particular interest is the Attr field. You can test Attr against the following attribute constants or values to determine if a file has a specific attribute:

Attribute constants and values

Constant Value Description

faReadOnly

$00000001

Read-only files

faHidden

$00000002

Hidden files

faSysFile

$00000004

System files

faVolumeID

$00000008

Volume ID files

faDirectory

$00000010

Directory files

faArchive

$00000020

Archive files

faAnyFile

$0000003F

Any file


To test for an attribute, combine the value of the Attr field with the attribute constant using the and operator. If the file has that attribute, the result will be greater than 0. For example, if the found file is a hidden file, the following expression will evaluate to True:

Delphi:

 (SearchRec.Attr and faHidden > 0)

C++:

 (SearchRec.Attr & faHidden > 0)

Attributes can be combined by OR'ing their constants or values. For example, to search for read-only and hidden files in addition to normal files, pass the following as the Attr parameter.

Delphi:

 (faReadOnly or faHidden).

C++:

 (faReadOnly | faHidden)

Example

The following example uses a label, a button named Search, and a button named Again on a form. When the user clicks the Search button, the first file in the specified path is found, and the name and the number of bytes in the file appear in the label's caption. Each time the user clicks the Again button, the next matching filename and size is displayed in the label:

Delphi:

 var SearchRec: TSearchRec;
 procedure TForm1.SearchClick(Sender: TObject);
 begin
   FindFirst('c:\Program Files\MyProgram\bin\*.*', faAnyFile, SearchRec); Label1.Caption := SearchRec.Name + ' is ' + IntToStr(SearchRec.Size) + ' bytes in size';
 end;
 procedure TForm1.AgainClick(Sender: TObject);
 begin
   if FindNext(SearchRec) = 0 then
     Label1.Caption := SearchRec.Name + ' is ' + IntToStr(SearchRec.Size) + ' bytes in size'
   else
     FindClose(SearchRec);
 end;

C++:

TSearchRec SearchRec; // global variable

void __fastcall TForm1::SearchClick(TObject *Sender) {
    FindFirst("c:\\Program Files\\bcb6\\bin\\*.*", faAnyFile, SearchRec);
    Label1->Caption = SearchRec->Name + " is " + IntToStr(SearchRec.Size) +
        " bytes in size";
}

void __fastcall TForm1::AgainClick(TObject *Sender) {
    if (FindNext(SearchRec) == 0)
        Label1->Caption = SearchRec->Name + " is " + IntToStr(SearchRec.Size) +
            " bytes in size";
    else
        FindClose(SearchRec);
}

Note: In cross-platform or multi-device applications, you should replace any hard-coded pathnames with the correct pathname for the system, or represent them using environment variables (listed on the Environment Variables page; choose Tools > Options > Environment Options > Environment Variables.

See Also