ExamineDirectory() :: Add Command To Get Number of Entries

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Tristano
Enthusiast
Enthusiast
Posts: 195
Joined: Thu Nov 26, 2015 6:52 pm
Location: Italy
Contact:

ExamineDirectory() :: Add Command To Get Number of Entries

Post by Tristano »

Currently there is no way to know how many entries ExamineDirectory() found. The only way around it seems to be restorting to a While NextDirectoryEntry() loop with a custom counter — something like this:

Code: Select all

Directory$ = GetHomeDirectory()
If ExamineDirectory(0, Directory$, "*.*")
  count = 0
  While NextDirectoryEntry(0)
    count + 1
  Wend
  Debug("Total items found: " + Str(count))
EndIf
It would very handy to have a command that returns the actual number of entries found by ExamineDirectory() — just like ListSize() does for lists! — so we could now the exact number of matched entries beforehand, without resorting to any loops.

Maybe it could be called DirectoryEntriesSize() (or something along those lines).

Such a command would allow to execute a boolean test on the examined Directory before actually iterating through a While NextDirectoryEntry() loop! — For example:

Code: Select all

Directory$ = GetHomeDirectory()
If ExamineDirectory(0, Directory$, "*.txt")
  If DirectoryEntriesSize(0)
    ; At least one *.txt file was found ...
    While NextDirectoryEntry(0)
      ; Do something with the txt files ...
    Wend
  Else
    Debug("No txt files found!")
  EndIf
EndIf
And, of course, it would allow to fork code execution based on the number of entries:

Code: Select all

If DirectoryEntriesSize(0) > 10
... and quickly compare results from two different directories:

Code: Select all

If DirectoryEntriesSize(0) > DirectoryEntriesSize(1)
This command would allow good code optimization when dealing with directories — both in execution speed as well as having to write less code.
The PureBASIC Archives: FOSS Resources:
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by freak »

There is no way to know the number of entries without iterating all of them. If we added such a command it would be exactly like the code you posted.
quidquid Latine dictum sit altum videtur
User avatar
Tristano
Enthusiast
Enthusiast
Posts: 195
Joined: Thu Nov 26, 2015 6:52 pm
Location: Italy
Contact:

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Tristano »

I see. It's a pity, it would have been useful.

Even though it wouldn't optimize execution time, wouldn't it still be worth it because it allows to get this info with a single command instead of writing a whole block?

At least it would make cleaner code.
The PureBASIC Archives: FOSS Resources:
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Little John »

Tristano wrote:Even though it wouldn't optimize execution time, wouldn't it still be worth it because it allows to get this info with a single command instead of writing a whole block?
At the beginning of your first post here, you almost wrote such a function yourself with a few lines ...
User avatar
Tristano
Enthusiast
Enthusiast
Posts: 195
Joined: Thu Nov 26, 2015 6:52 pm
Location: Italy
Contact:

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Tristano »

Little John wrote:
Tristano wrote:Even though it wouldn't optimize execution time, wouldn't it still be worth it because it allows to get this info with a single command instead of writing a whole block?
At the beginning of your first post here, you almost wrote such a function yourself with a few lines ...
... true! Surely, writing some custom procedures to similar tasks is not a big issue. But lazyness is a blessing! :wink:

I didn't realize that it wasn't possible to know the items total number before actually iterating them — I now guess that this is because ExamineDirectory() relies on OS functionality.

Even a simple boolean True/False value would have been a good feature, just to check if there are any entries at all.

What can I say ... I tried :D — after all features requests are about ideas of what might be useful, provided they are implementable.
The PureBASIC Archives: FOSS Resources:
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Little John »

Tristano wrote:Even a simple boolean True/False value would have been a good feature, just to check if there are any entries at all.
I did understand your original wish. :-)
However, in the meantime freak has explained the situation.
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by helpy »

Tristano wrote:Even a simple boolean True/False value would have been a good feature, just to check if there are any entries at all.
NextDirectory() already does a similar thing! If there is no entry at all it returns zero!
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
tj1010
Enthusiast
Enthusiast
Posts: 716
Joined: Mon Feb 25, 2013 5:51 pm

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by tj1010 »

this would be nice, but it'd still have to do this because extension mask:

Code: Select all

Procedure.l countem(path$,mask$)
  Protected dir.l
  Protected counter.l
  CompilerIf #PB_Compiler_OS=#PB_OS_Windows
    If Mid(path$,Len(path$),1)<>"\" : path$=path$+"\" : EndIf
  CompilerElse
    If Mid(path$,Len(path$),1)<>"/" : path$=path$+"/" : EndIf
  CompilerEndIf
  If FileSize(path$)=-2
    dir=ExamineDirectory(#PB_Any,path$,mask$)
    If dir
      While NextDirectoryEntry(dir)
        If DirectoryEntryName(dir)<>".." And DirectoryEntryName(dir)<>"."
          If DirectoryEntryType(dir)=#PB_DirectoryEntry_File
            counter=counter+1
          Else
            CompilerIf #PB_Compiler_OS=#PB_OS_Windows
              counter=counter+countem(path$+DirectoryEntryName(dir)+"\",mask$)
            CompilerElse
              counter=counter+countem(path$+DirectoryEntryName(dir)+"/",mask$)
            CompilerEndIf
          EndIf
        EndIf
      Wend
      FinishDirectory(dir)
    EndIf
  EndIf
  ProcedureReturn counter
EndProcedure

Debug countem(PathRequester("Pick A Folder",GetCurrentDirectory()),"*.*")
Last edited by tj1010 on Sun Jul 02, 2017 6:10 am, edited 1 time in total.
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Dude »

nvm
Last edited by Dude on Tue Jul 04, 2017 5:40 am, edited 1 time in total.
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Little John »

helpy wrote:NextDirectory() already does a similar thing!
It seems you mean NextDirectoryEntry(). :-)
helpy wrote:If there is no entry at all it returns zero!
It returns 0 on first call only in case of an error. There is always the entry "." and except for thr root directory there is also ".." (at least on Windows).
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by helpy »

Little John wrote:
helpy wrote:NextDirectory() already does a similar thing!
It seems you mean NextDirectoryEntry(). :-)
Yes! You are right!

Little John wrote:
helpy wrote:If there is no entry at all it returns zero!
It returns 0 on first call only in case of an error. There is always the entry "." and except for thr root directory there is also ".." (at least on Windows).
Not always. I only tested mask *.pdf and *.txt
In this case no entry "." or ".." is returned....

Yes. You are right, we should always do tests, if entry is a file or a directory and if entry is "." or "..".
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
Little John
Addict
Addict
Posts: 4779
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Little John »

helpy wrote:Not always. I only tested mask *.pdf and *.txt
In this case no entry "." or ".." is returned....
Doh, I didn't think of the mask ... You are right.
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Olliv »

First remark

Problem in your wish is that an entry can be more than just one thing :

1) a file
2) either a sub-directory

If you explore a directory one first time to get the number of entries, the new idea you will have is a new feature to get the count of files in one directory.

Also PureBasic concept is not actually based to a stored structured syntax, usable like this :

Code: Select all

Structure DirContent
      TotalCount.I
      FileCount.I
EndStructure

Define DirCtn.DirContent
GetDirContent(DirCtn)
Debug Str(DirCtn\FileCount) + " files"
Debug Str(DirCtn\TotalCount) + " entries"
If it was, it should :

Code: Select all

ExamineDirectoryContent()
 Debug Str(GetFileCount() ) + " files"
Debug Str(GetDirTotalCount() ) + " entries"
Then it would not be one but three new statements !


2nd remarkIt seems that '/' is cross-platform. No need to use a compiler directive to pre-select a '/' character or a '\' character, depending of the OS. Do I mistake?

3nd remarkI am surprised it is unable to get more infos about a directory. Is this due to various length of file name?
User avatar
Tristano
Enthusiast
Enthusiast
Posts: 195
Joined: Thu Nov 26, 2015 6:52 pm
Location: Italy
Contact:

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by Tristano »

Olliv wrote:2nd remarkIt seems that '/' is cross-platform. No need to use a compiler directive to pre-select a '/' character or a '\' character, depending of the OS. Do I mistake?
Windows will accept "/" as a path separator, but any commands dealing with file paths will always return "\" as a separator because it's Win default. So, any cross-platform code will have to take in account that on Win when retriving file/folder paths.

From this thread it seems like there can't be a single solution to fit all needs. Probably the best solution would be to have a collection of different PB examples/procedures to pick from to handle this (ie: cross-platform, platform-dependent, etc.).

About the "." and ".." entries found on Windows, are there similar equivalents on Linux and Mac? In my code I already handle "." and ".." on Win OS, but I was wondering if and what to except on Mac (which I don't have access to) in order to make it cross platform.

PS: I think that the documentation ought to mention "." and ".." on Win, and other similar cases on other OSs, so users can keep it in mind for cross-platform code's sake.
The PureBASIC Archives: FOSS Resources:
tj1010
Enthusiast
Enthusiast
Posts: 716
Joined: Mon Feb 25, 2013 5:51 pm

Re: ExamineDirectory() :: Add Command To Get Number of Entri

Post by tj1010 »

Symlinks and alt-streams are the only real issues. My code works on Debian, OSX, and Windows with no problems. I could of used RunProgram for privilege escalation.

I avoid API as much as possible especially on Linux..
Post Reply