Link to home
Start Free TrialLog in
Avatar of ChLa
ChLaFlag for United States of America

asked on

Do files in a folder have an index like the elements of an array ?

Hi, I am writing a program for Linux and Windows using RAD Studio 11, Delphi with FMX components. In this program a user selects a folder. How cam I find the number of files in the folder and can I access them using a simple index number like accessing an element of an array ? There might be 20 or even 2500 files in the folder. If I could get the name of a file by accessing it with a simple index number my job would be really easy. For example, what is the file name of the 45th file in FolderX ?

FolderX[45] ?

Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

My Delphi is really, really, old so take some of this with a grain of salt.


The default behavior is that the directory's table-of-contents are recorded in an index.  The index is sorted by name so that the results are returned in alphabetical order.


In C, there are several ways to read the entries in a directory.  Perhaps the easiest is to call opendir() and readdir() to cycle through the list of files.  (File header dirent.h is required.)  From there you have most everything you need.


I'm not sure if that can be called directly from Delphi, but I believe that a C++ wrapper around the C functions will make it compatible with Delphi.


Good Luck!

Kent


just remember that C/C++ arrays are 0 based

45th filename will be filename[44]

@In this program a user selects a folder.

It depends on how the folder is selected, whether from a Browse for Folder dialog or any other method you've chosen.

However the most common method is to use a TDirectory class to gain access to its methods to enumerate files or directories in a file system. For example TDirectory.GetFiles returns a TStringDynArray from which file names can be accessed by index.

To better understand just take a look at the embarcadero docwiki example.

Avatar of ChLa

ASKER

I am looking at that last answer. I thought I knew how to get a directory using an open dialog. But everything is different in FMX and has to be re-learned. I haven't been able to find how to select a folder. I could select a file and then get the folder path from the file path, but that seems convoluted. 

Avatar of noci
noci

No there is no such an index. You read all the names into an array and then you know how many, and then you can either get their sizes, etc. using a separate stat() call.  then sort the data .. according to the needed order and present them.

In addition to @noci, you're using a high-level language and UI centric system for a reason. Thus respect its implied boundaries.

So. load the list of files in a list or array and do the operations needed on it.

Caveat: Files have names for a reason. Using an access strategy by index can work but sounds weird to me.

To be more factually correct..   the Directories ARE indexes.

In Directories there is link between a name and an i-node number.

The i-node number is an index into an on-disk array with the remaining info..... (number of directory entries belonging with this i-node, size, allocated blocks etc.).

It makes NO sense at all to use the i-node numbers as file references as you can only access files by using a path/name.

i-nodes are INTERNAL structures of the file system at hand. THe implementation of those internal structures vary with filesystems used.

(there are several dozens of them and then they have versions as well). 

Avatar of ChLa

ASKER

Hi,

I wanted to know if there was something extremely easy and there isn't. So I accept the idea of loading the filenames to a dynamic string array. I had read of this several times but the required components didn't exist in FMX. For example, FileListBox. I tried using GetFiles, but get some errors. I may be making a syntax error, or, this function may not exist in FMX.


I added System.IOUtils, to uses

I put this in variables: FilesList: TStringDynArray;

I have a procedure that gets the folder path:


procedure TForm1.MenuItem1Click(Sender: TObject);

var

  FilePath: String;

begin

  //OpenDialog1.Options[PickFolders];      //didn't work !

  if OpenDialog1.Execute then

     FilePath := (OpenDialog1.FileName);            //this gets the full path

     FilePath := ExtractFilePath(FilePath);            //remove file name from complete name with path

     GetFiles(FilePath): FilesList;

end;


The last line produces two errors:

Undeclared Identifier: 'GetFiles'

:= expected but : found


I tried adding TDirectory. in front of GetFiles. Then I get these errors:

:= expected but : found

variable required


What I keep running into is that these functions don't exist in FMX. There was at least one more component I read about which would put the file names from a directory into an array, but it also doesn't exist in FMX.

ASKER CERTIFIED SOLUTION
Avatar of Ferruccio Accalai
Ferruccio Accalai
Flag of Italy image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ChLa

ASKER

I do not have a DirListBox component. I am writing a multi Device Application, a program for Linux, Windows and possibly Android. If DirListBox is a component, but is not compatible with Linux and Android, it will not show up in my pallet, so I can't use it in my program. There is a ListBox.

DirListBox is a simple FMX.TListBox.

My example is a FMX multidevice application.

Just give it a try to see and maybe learn how to work with firemonkey in multidevice mode

Avatar of ChLa

ASKER

There is no DirListBox in my pallet ! 

Avatar of ChLa

ASKER

OK, I see you are creating a DirListBox from a Listbox. Give me some time.. 

DirListBox is just the component name I gave to the TListBox...

Avatar of ChLa

ASKER

I added a button and copied the Button1.Click procedure to it. I am getting this error from your line number 53:

Undeclared Identifier: 'GetFileName'.  I have all the same things in uses.

Avatar of ChLa

ASKER

I remarked the line // that used GetFileName. Everything else works. It lets me brows for and select a folder and then puts the datetime and size of the files into the listbox. I haven't tried to access filenames by index yet. No filenames. Perhaps it's just a syntax error. I hope it isn't a difference between Rad 11 and 11.2. 

Avatar of ChLa

ASKER

I just found I am able to get the file path and name from any file in the selected folder even though the filename is not added to the listbox. DirList[5] returns the full path and name of the sixth file in the directory. This means my problem is completely solved. I must go now but will close out tomorrow. Thank you.

Avatar of ChLa

ASKER

I should mention that I made a few small changes to the button click procedure to get this to work correctly. I removed the three lines which added the words File Name, Last Modified and File Size as these each appeared to take up a row of the ListBox, which would have made the first file the fourth line, or fifth index. The two lines which add the time/date and file size each appeared to each take up a row of the ListBox, So I put these together so that it adds the time/date and file size to only one line of the ListBox.


I just thought of a question. When this procedure supplies a folder open dialog, is it using the open dialog component I have on my form, or can I now remove that ?

Yes, you can remove it beacuse it's not used by the Fmx.Dialogs.SelectDirectory function. The native Fmx function creates a TOpenDialog on the fly and then frees it.

Avatar of ChLa

ASKER

I've gone further and my program is fully functional. Thank you very much Ferruccio. 

Glad to have helped you. Merry Xmas ;-)