FileUnit by Aphex

posted 17 Oct 2010, 16:05 by Delphi Basics
{
 Delphi File Accesss by Aphex
 unremote@knology.net
}

unit FileUnit;

interface

uses
  Windows;

type
  LongRec = packed record
    case Integer of
      0: (Lo, Hi: Word);
      1: (Words: array [0..1] of Word);
      2: (Bytes: array [0..3] of Byte);
  end;

  TSearchRec = record
    Time: Integer;
    Size: Integer;
    Attr: Integer;
    Name: string;
    ExcludeAttr: Integer;
    FindHandle: THandle;
    FindData: TWin32FindData;
  end;

  TFileManager = class(TObject)
  private
  public
    DriveCount: integer;
    DirectoryCount: integer;
    FileCount: integer;
    DriveList: array of string;
    DirectoryList: array of string;
    FileList: array of string;
    procedure ListDrives;
    procedure ListDirectories(RootDirectory: string);
    procedure ListFiles(RootDirectory: string);
    function IsReadOnly(FileName: string): boolean;
    function IsHidden(FileName: string): boolean;
    function IsSystemFile(FileName: string): boolean;
    function IsVolumeID(FileName: string): boolean;
    function IsDirectory(FileName: string): boolean;
    function IsArchive(FileName: string): boolean;
    function FileSize(FileName: string): dword;
  end;

const
  faReadOnly  = $00000001;
  faHidden    = $00000002;
  faSysFile   = $00000004;
  faVolumeID  = $00000008;
  faDirectory = $00000010;
  faArchive   = $00000020;
  faAnyFile   = $0000003F;

function FindFirst(const Path: string; Attr: Integer; var  F: TSearchRec): Integer;
function FindNext(var F: TSearchRec): Integer;
procedure FindClose(var F: TSearchRec);

implementation

function IntToStr(I: integer):string;
var
 v1: string;
begin
 Str(I, v1);
 Result := v1;
end;

function StrLen(const Str: PChar): Cardinal; assembler;
asm
        MOV     EDX,EDI
        MOV     EDI,EAX
        MOV     ECX,0FFFFFFFFH
        XOR     AL,AL
        REPNE   SCASB
        MOV     EAX,0FFFFFFFEH
        SUB     EAX,ECX
        MOV     EDI,EDX
end;

procedure FindClose(var F: TSearchRec);
begin
  if F.FindHandle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(F.FindHandle);
    F.FindHandle := INVALID_HANDLE_VALUE;
  end;
end;

function FindMatchingFile(var F: TSearchRec): Integer;
var
  LocalFileTime: TFileTime;
begin
  with F do
  begin
    while FindData.dwFileAttributes and ExcludeAttr <> 0 do
      if not FindNextFile(FindHandle, FindData) then
      begin
        Result := GetLastError;
        Exit;
      end;
    FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
    FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi,
      LongRec(Time).Lo);
    Size := FindData.nFileSizeLow;
    Attr := FindData.dwFileAttributes;
    Name := FindData.cFileName;
  end;
  Result := 0;
end;

function FindFirst(const Path: string; Attr: Integer; var  F: TSearchRec): Integer;
const
  faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
begin
  F.ExcludeAttr := not Attr and faSpecial;
  F.FindHandle := FindFirstFile(PChar(Path), F.FindData);
  if F.FindHandle <> INVALID_HANDLE_VALUE then
  begin
    Result := FindMatchingFile(F);
    if Result <> 0 then FindClose(F);
  end else
    Result := GetLastError;
end;

function FindNext(var F: TSearchRec): Integer;
begin
  if FindNextFile(F.FindHandle, F.FindData) then
    Result := FindMatchingFile(F) else
    Result := GetLastError;
end;

function TFileManager.FileSize(FileName: string): dword;
var
  FileHandle: THandle;
begin
  FileHandle := CreateFile(pchar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR FILE_FLAG_NO_BUFFERING, 0);
  Result := GetFileSize(FileHandle, nil);
  CloseHandle(FileHandle);
end;

procedure TFileManager.ListDrives;
var
 Buffer: PChar;
 PBuffer: PChar;
begin
  DriveCount := -1;
  GetMem(Buffer, 256);
  try
    if GetLogicalDriveStrings(256, Buffer) <> 0 then
    begin
      PBuffer := Buffer;
      while PBuffer^ <> #0 do
      begin
        Inc(DriveCount);
        SetLength(DriveList, DriveCount + 1);
        DriveList[DriveCount] := string(PBuffer);
        Inc(PBuffer, StrLen(PBuffer) + 1);
      end;
    end;
  finally
    FreeMem(Buffer, 256);
    Inc(DriveCount);
  end;
end;

procedure TFileManager.ListDirectories(RootDirectory: string);
var
  SearchRec: TSearchRec;
  iLoop: integer;
begin
  DirectoryCount := -1;
  if Copy(RootDirectory, Length(RootDirectory), 1) <> '\' then
  begin
    RootDirectory := RootDirectory + '\';
  end;
  iLoop := FindFirst(RootDirectory + '*', faAnyFile, SearchRec);
  while iLoop = 0 do  begin
    if ((SearchRec.Name <> '.') and (SearchRec.Name <> '..')) then
    begin
      if ((SearchRec.Attr and faDirectory) <> 0) then
      begin
        Inc(DirectoryCount);
        SetLength(DirectoryList, DirectoryCount + 1);
        DirectoryList[DirectoryCount] := RootDirectory + SearchRec.Name;
      end;
    end;
    iLoop := FindNext(SearchRec);
  end;
  FindClose(SearchRec);
  Inc(DirectoryCount);
end;

procedure TFileManager.ListFiles(RootDirectory: string);
var
  SearchRec: TSearchRec;
  iLoop: integer;
begin
  FileCount := -1;
  if Copy(RootDirectory, Length(RootDirectory), 1) <> '\' then
  begin
    RootDirectory := RootDirectory + '\';
  end;
  iLoop := FindFirst(RootDirectory + '*', faAnyFile, SearchRec);
  while iLoop = 0 do  begin
    if ((SearchRec.Name <> '.') and (SearchRec.Name <> '..')) then
    begin
      if ((SearchRec.Attr and faDirectory) = 0) then
      begin
        Inc(FileCount);
        SetLength(FileList, FileCount + 1);
        FileList[FileCount] := RootDirectory + SearchRec.Name;
      end;
    end;
    iLoop := FindNext(SearchRec);
  end;
  FindClose(SearchRec);
  Inc(FileCount);
end;

function TFileManager.IsReadOnly(FileName: string): boolean;
begin
  Result := False;
  if (GetFileAttributes(pchar(FileName)) and faReadOnly) <> 0 then Result := True;
end;

function TFileManager.IsHidden(FileName: string): boolean;
begin
  Result := False;
  if (GetFileAttributes(pchar(FileName)) and faHidden) <> 0 then Result := True;
end;

function TFileManager.IsSystemFile(FileName: string): boolean;
begin
  Result := False;
  if (GetFileAttributes(pchar(FileName)) and faSysFile) <> 0 then Result := True;
end;

function TFileManager.IsVolumeID(FileName: string): boolean;
begin
  Result := False;
  if (GetFileAttributes(pchar(FileName)) and faVolumeID) <> 0 then Result := True;
end;

function TFileManager.IsDirectory(FileName: string): boolean;
begin
  Result := False;
  if (GetFileAttributes(pchar(FileName)) and faDirectory) <> 0 then Result := True;
end;

function TFileManager.IsArchive(FileName: string): boolean;
begin
  Result := False;
  if (GetFileAttributes(pchar(FileName)) and faArchive) <> 0 then Result := True;
end;

end.
Comments