2

There's some way to determine with precision if a given path is a FILE or FOLDER?

If yes, could show a example please? Thanks in advance.

2 Answers2

10

You can use the RTL's TPath.GetAttributes(), TFile.GetAttributes() or TDirectory.GetAttributes() method, eg:

uses
  ..., System.IOUtils;

try
  if TFileAttribute.faDirectory in TPath{|TFile|TDirectory}.GetAttributes(path) then
  begin
    // path is a folder ...
  end else
  begin
    // path is a file ...
  end;
except
  // error ...
end;

Or, you can use the Win32 API GetFileAttributes() or GetFileAttributesEx() function directly, eg:

uses
  ..., Winapi.Windows;

var
  attrs: DWORD;
begin
  attrs := Windows.GetFileAttributes(PChar(path));
  if attrs = INVALID_FILE_ATTRIBUTES then
  begin
    // error ...
  end
  else if (attrs and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
  begin
    // path is a folder ...
  end else
  begin
    // path is a file ...
  end;
end;
uses
  ..., Winapi.Windows;

var
  data: WIN32_FILE_ATTRIBUTE_DATA;
begin
  if not Windows.GetFileAttributesEx(PChar(path), GetFileExInfoStandard, @data) then
  begin
    // error ...
  end
  else if (data.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
  begin
    // path is a folder ...
  end else
  begin
    // path is a file ...
  end;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Seeing WIN32 API option above, is realiable test `INVALID_FILE_ATTRIBUTES` to check if file/folder exists? –  Aug 31 '20 at 19:03
  • 1
    [Potentially yes](https://devblogs.microsoft.com/oldnewthing/20071023-00/?p=24713), as long as you don't need to deal with `FILE_ATTRIBUTE_REPARSE_POINT`, which would require more work to determine if the target file/folder actually exists or not. – Remy Lebeau Aug 31 '20 at 19:39
  • How do you know when to use TPath|TFile|TDirectory? You just receive a string. You don't know if it is a file or directory. – Gabriel Feb 20 '23 at 17:16
  • @GabrielMoraru I don't use them myself at all. However, if the file/folder exists, you can use `TPath.GetAttributes()` to differentiate between them (via the presence or lack of the `faDirectory` attribute). – Remy Lebeau Feb 20 '23 at 17:34
  • "if the file/folder exists, you can use...." - Ok. But then my function (see my answer) should suffice. Right? – Gabriel Feb 20 '23 at 18:22
  • @GabrielMoraru your function will "work", but I would not recommend it, as it is less efficient – Remy Lebeau Feb 20 '23 at 18:28
  • But you advocate using the functions as me (FileExists/DirectoryExists). How can my function be less efficient in this case? – Gabriel Feb 20 '23 at 19:26
  • @GabrielMoraru "*you advocate using the functions as me (FileExists/DirectoryExists)*" - I said no such thing. But, `FileExists()` and `DirectoryExists()` both use `GetFileAttributes()` internally. As for efficiency, your *original* function was doing 2 separate checks (using the same underlying API twice) which is less efficient than doing 1 single check, as the code in my answer is doing. However, you have since changed your code to remove one of the checks. – Remy Lebeau Feb 20 '23 at 20:06
  • Sorry, I interpreted wrong your statement: "if the file/folder exists". I understand now. – Gabriel Feb 21 '23 at 08:31
0
// Note: the folder must exist.
function IsFolder(CONST FullPath: string): boolean;
begin
 Result:= {NOT FileExists(FullPath) AND} DirectoryExists(FullPath);
end;
Gabriel
  • 20,797
  • 27
  • 159
  • 293