Navid Madani 1 Posted February 23 (edited) TDirectory.GetFiles in System.IOUtils has a bug on macOS: In the returned dynamic string array, valid files with names that contain three or four consecutive periods are not included. I ended up having to use macOS system functions instead. If it would help others who could run into this problem, my solution is below. Please post if you find any errors. macOS programming is certainly not my forte. unit Nm.IOUtils; interface uses System.SysUtils , System.Types {$IFDEF MACOS} , Macapi.ObjectiveC , Macapi.CocoaTypes , Macapi.Foundation , Macapi.Helpers {$ENDIF} ; {$IFDEF MACOS} type EItemType = (itFiles, itDirectories); EItemTypes = set of EItemType; function macOS_GetDirectoryContents(const DirectoryPath: string; const ItemTypes: EItemTypes): TStringDynArray; {$ENDIF} implementation {$IFDEF MACOS} function macOS_GetDirectoryContents(const DirectoryPath: string; const ItemTypes: EItemTypes): TStringDynArray; const ARRAYSIZEINCREMENT = 32; var FileManager: NSFileManager; URL, FileURL: NSURL; FileEnum: NSDirectoryEnumerator; Options: NSDirectoryEnumerationOptions; Error: NSError; IsDirectoryVal: Pointer; IsDirectory: Boolean; Candidate: string; i: Integer; ArraySize: Integer; begin FileManager := TNSFileManager.Wrap(TNSFileManager.OCClass.defaultManager); URL := TNSURL.Wrap(TNSURL.OCClass.fileURLWithPath(StrToNSStr(DirectoryPath), True)); Options := NSDirectoryEnumerationSkipsSubdirectoryDescendants; FileEnum := FileManager.enumeratorAtURL(URL, nil, Options, nil); FileURL := TNSURL.Wrap(FileEnum.nextObject); ArraySize := ARRAYSIZEINCREMENT; SetLength(Result, ArraySize); i := 0; while Assigned(FileURL) and FileURL.isFileURL do begin IsDirectoryVal := nil; if FileURL.getResourceValue(@IsDirectoryVal, StrToNSStr('NSURLIsDirectoryKey'), @Error) and Assigned(IsDirectoryVal) then begin if i >= ArraySize then begin Inc(ArraySize, ARRAYSIZEINCREMENT); SetLength(Result, ArraySize); end; Candidate := UTF8ToString(FileURL.path.UTF8String); IsDirectory := TNSNumber.Wrap(IsDirectoryVal).boolValue; if IsDirectory then begin if (itDirectories in ItemTypes) then begin Result[i] := Candidate; Inc(i); end; end else begin if (itFiles in ItemTypes) then begin Result[i] := Candidate; Inc(i); end; end; end; FileURL := TNSURL.Wrap(FileEnum.nextObject); end; SetLength(Result, i); end; {$ENDIF} end. Edited February 23 by Navid Madani Discriminate between files and directories Share this post Link to post