Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
{$APPTYPE CONSOLE}
program test1; uses sysutils;
{ test program #1 for FindFirst/FindNext FAQ by Glenn9999,
demonstrates testing for attributes }
procedure writeattr(inattr: longint);
{ tests file attributes and writes out a corresponding letter for it }
begin
{ list of file attributes }
if (inattr and faReadOnly) = faReadOnly then
write('R');
if (inattr and faHidden) = faHidden then
write('H');
if (inattr and faSysFile) = faSysFile then
write('S');
if (inattr and faVolumeID) = faVolumeID then
write('V');
if (inattr and faDirectory) = faDirectory then
write('D');
if (inattr and faArchive) = faArchive then
write('A');
end;
var
SR: TSearchRec;
retcode: integer;
begin
retcode := FindFirst('C:\*.*', faAnyFile, SR);
while retcode = 0 do
begin
write(SR.Name, '(':30-Length(SR.Name));
writeattr(Sr.Attr);
writeln(')');
retcode := FindNext(SR);
end;
FindClose(SR);
readln;
end.
AUTOEXEC.BAT (A)
BJPrinter (HD)
boot.ini (RHSA)
CONFIG.SYS (A)
Documents and Settings (D)
error.log (A)
FSC (D)
IO.SYS (RHSA)
MSDOS.SYS (RHSA)
NTDETECT.COM (RHSA)
ntldr (RHSA)
pagefile.sys (HSA)
Program Files (RD)
RECYCLER (HSD)
sqmdata00.sqm (HA)
sqmnoopt00.sqm (HA)
System Volume Information (HSD)
WINDOWS (D)
AUTOEXEC.BAT (A)
CONFIG.SYS (A)
Documents and Settings (D)
error.log (A)
FSC (D)
Program Files (RD)
WINDOWS (D)
FindFirst searches the directory specified by Path for the first file that matches the file name implied by Path and the attributes specified by the Attr parameter.
..
Attributes can be combined by adding their constants or values. For example, to search for read-only and hidden files in addition to normal files, pass (faReadOnly + faHidden) the Attr parameter.
unit sfffn;
{ unit to encapsulate new FindFirst/FindNext/FindClose. Certain
optimizations were made compared to the sysutil versions - most
important being the fact that the functions in this unit will
*STRICTLY* filter attributes presented to it. So don't expect this
version to act like the Sysutils version.
Example: faDirectory in Attr only returns directories.
faHidden+faSysFile only returns files /directories
with BOTH attributes
This means there shouldn't be a need for post-filtering unless you
want to "OR" the attributes - like if you want to return either
faHidden or faSysFile. To that end, this should present an
improvement in that realm.
The relevant definitions from Sysutils were copied into this source file
so the added weight of Sysutils is not necessary if all you do is
search files. Certain helps were also gotten from the Sysutils source.
Functions in this unit:
SFindFirst; Like the FindFirst
SFindNext; Like the FindNext
SFindClose; Like the FindClose }
interface
uses windows;
const
faReadOnly = $00000001;
faHidden = $00000002;
faSysFile = $00000004;
{ faVolumeID = $00000008; faVolumeID seems not used in Windows anyway }
faDirectory = $00000010;
faArchive = $00000020;
faAnyFile = $0000003F;
type
TFileName = string;
LongRec = packed record
Lo, Hi: Word;
end;
TSearchRec = record
Time: Integer;
Size: Integer;
Attr: Integer;
Name: TFileName;
ExcludeAttr: Integer;
FindHandle: THandle;
FindData: TWin32FindData;
end;
function SFindFirst(const Path: string; Attr: Integer;
var F: TSearchRec): Integer;
function SFindNext(var F: TSearchRec): Integer;
procedure SFindClose(F: TSearchRec);
implementation
procedure move_rec(var F: TSearchRec);
var
LocalFileTime: TFileTime;
begin
with F do
begin
Size := FindData.nFileSizeLow;
Attr := FindData.dwFileAttributes;
Name := FindData.cFileName;
FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
FileTimeToDosDateTime(LocalFileTime, LongRec(F.Time).Hi,
LongRec(F.Time).Lo);
end;
end;
function SFindFirst(const Path: string; Attr: Integer;
var F: TSearchRec): Integer;
const
faSpecial = faHidden or faSysFile or faDirectory;
var
ret: boolean;
begin
if Attr = faAnyFile then
F.ExcludeAttr := not Attr and faSpecial
else
F.ExcludeAttr := Attr;
F.FindHandle := FindFirstFile(PChar(Path), F.FindData);
if F.FindHandle <> INVALID_HANDLE_VALUE then
begin
while (F.FindData.dwFileAttributes and F.ExcludeAttr) <> F.ExcludeAttr do
begin
ret := FindNextFile(F.FindHandle, F.FindData);
if (not ret) then
begin
Result := GetLastError;
exit;
end;
end;
move_rec(F);
Result := 0;
end
else
Result := GetLastError;
end;
function SFindNext(var F: TSearchRec): Integer;
var
ret: boolean;
begin
repeat
ret := FindNextFile(F.FindHandle, F.FindData);
if (not ret) then break;
until (F.FindData.dwFileAttributes and F.ExcludeAttr) = F.ExcludeAttr;
move_rec(F);
if ret then
Result := 0
else
Result := GetLastError;
end;
procedure SFindClose(F: TSearchRec);
{ copied from SysUtils source - nothing changes for this }
begin
if F.FindHandle <> INVALID_HANDLE_VALUE then
Windows.FindClose(F.FindHandle);
end;
end.
BJPrinter (HD)
Documents and Settings (D)
FSC (D)
Program Files (RD)
RECYCLER (HSD)
System Volume Information (HSD)
WINDOWS (D)
unit bfffn;
{ unit to encapsulate new FindFirst/FindNext/FindClose.
This is a bare version which does not take attribute in any form and will
return all files - ideal for post-filtering algorithms. Performance
improvements can be made which departs from the TSearchRec structure to
TWin32FindData, but those will not be made within this unit.
The relevant definitions from Sysutils were copied into this source file
so the added weight of Sysutils is not necessary if all you do is
search files. Certain helps were also gotten from the Sysutils source.
Functions in this unit:
BFindFirst; Like the FindFirst
BFindNext; Like the FindNext
BFindClose; Like the FindClose }
interface
uses windows;
const
faReadOnly = $00000001;
faHidden = $00000002;
faSysFile = $00000004;
{ faVolumeID = $00000008; faVolumeID seems not used in Windows anyway }
faDirectory = $00000010;
faArchive = $00000020;
faAnyFile = $0000003F;
type
TFileName = string;
LongRec = packed record
Lo, Hi: Word;
end;
TSearchRec = record
Time: Integer;
Size: Integer;
Attr: Integer;
Name: TFileName;
ExcludeAttr: Integer;
FindHandle: THandle;
FindData: TWin32FindData;
end;
{ attribute not specified in BFindFirst! }
function BFindFirst(const Path: string; var F: TSearchRec): Integer;
function BFindNext(var F: TSearchRec): Integer;
procedure BFindClose(F: TSearchRec);
implementation
procedure move_rec(var F: TSearchRec);
var
LocalFileTime: TFileTime;
begin
with F do
begin
Size := FindData.nFileSizeLow;
Attr := FindData.dwFileAttributes;
Name := FindData.cFileName;
FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
FileTimeToDosDateTime(LocalFileTime, LongRec(F.Time).Hi,
LongRec(F.Time).Lo);
end;
end;
function BFindFirst(const Path: string; var F: TSearchRec): Integer;
begin
F.FindHandle := Windows.FindFirstFile(PChar(Path), F.FindData);
if F.FindHandle <> INVALID_HANDLE_VALUE then
begin
move_rec(F);
Result := 0;
end
else
Result := GetLastError;
end;
function BFindNext(var F: TSearchRec): Integer;
var
ret: boolean;
begin
ret := Windows.FindNextFile(F.FindHandle, F.FindData);
if ret then
begin
move_rec(F);
Result := 0;
end
else
Result := GetLastError;
end;
procedure BFindClose(F: TSearchRec);
{ copied from SysUtils source - nothing changes for this }
begin
if F.FindHandle <> INVALID_HANDLE_VALUE then
Windows.FindClose(F.FindHandle);
end;
end.
{$APPTYPE CONSOLE}
{$DEFINE NODEBUG}
program test4; uses sysutils;
{ test program #4 for FindFirst/FindNext FAQ by Glenn9999,
allows for benchmarking of file seeking performance.
parses through all directories, optionally writing all the results}
type
DWord = Longint;
{ a timing routine }
function TimeMS: DWord;
stdcall; external 'winmm.dll' name 'timeGetTime';
procedure listdirectory(indir: string);
var
SR: TSearchRec;
retcode: integer;
begin
{$IFDEF DEBUG }
writeln(indir);
{$ENDIF}
retcode := FindFirst(indir + '\*.*', faAnyFile, SR);
while retcode = 0 do
begin
{$IFDEF DEBUG }
writeln(SR.Name);
{$ENDIF}
if (SR.Attr and FaDirectory) = faDirectory then
begin
if (SR.Name <> '.') and (SR.Name <> '..') then
ListDirectory(indir + '\' + SR.Name);
end;
retcode := FindNext(SR);
end;
Findclose(SR);
end;
var
STime: Longint;
numtimes, i: longint;
begin
write('Number of times to run: ');
readln(numtimes);
STime := TimeMS;
for i := 1 to numtimes do
listdirectory('C:');
STime := TimeMS - STime;
write('Program completed in ', STime, ' ms. Press Enter to Exit.');
readln;
end.
{$APPTYPE CONSOLE}
{$DEFINE NODEBUG}
program test7; uses windows;
{ test program #7 for FindFirst/FindNext FAQ by Glenn9999,
allows for benchmarking of file seeking performance.
parses through all directories, optionally writing all the results
change define to DEBUG in order to write the directory paths and names
TWin32FindDataA = record
dwFileAttributes: DWORD;
ftCreationTime: TFileTime;
ftLastAccessTime: TFileTime;
ftLastWriteTime: TFileTime;
nFileSizeHigh: DWORD;
nFileSizeLow: DWORD;
dwReserved0: DWORD;
dwReserved1: DWORD;
cFileName: array[0..MAX_PATH - 1] of AnsiChar;
cAlternateFileName: array[0..13] of AnsiChar;
end;
}
const
faDirectory = $00000010;
type
DWord = Longint;
{ a timing routine }
function TimeMS: DWord;
stdcall; external 'winmm.dll' name 'timeGetTime';
procedure listdirectory(indir: string);
var
SR: TWin32FindData;
retcode, FindHandle: integer;
begin
{$IFDEF DEBUG }
writeln(indir);
{$ENDIF}
FindHandle := Windows.FindFirstFile(PChar(Indir + '\*.*'), SR);
if FindHandle <> INVALID_HANDLE_VALUE then
Retcode := 0
else
Retcode := GetLastError;
while retcode = 0 do
begin
{$IFDEF DEBUG }
writeln(SR.cFileName);
{$ENDIF}
if (SR.dwFileAttributes and FaDirectory) = faDirectory then
begin
if (String(SR.cFileName) <> '.') and (String(SR.cFileName) <> '..') then
ListDirectory(indir + '\' + SR.cFileName);
end;
if Windows.FindNextFile(FindHandle, SR) then
Retcode := 0
else
Retcode := GetLastError;
end;
if FindHandle <> INVALID_HANDLE_VALUE then
Windows.FindClose(FindHandle);
end;
var
STime: Longint;
numtimes, i: longint;
begin
write('How many times to run: ');
readln(numtimes);
STime := TimeMS;
for i := 1 to numtimes do
listdirectory('C:');
STime := TimeMS - STime;
write('Program completed in ', STime, ' ms. Press Enter to Exit.');
readln;
end.