Determine if a folder does not exists OR it has no content

Please check the FAQ (https://www.xyplorer.com/faq.php) before posting a question...
klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Determine if a folder does not exists OR it has no content

Post by klownboy »

I've been struggling with a method to determine if a folder either does not exist OR it has no contents (files or folders). I can use "exists" to determine if the folder exist and I can use "folderreport" to determine if the folder contains no file or folders. My problem is folderreport or even foldersize will give you an error message if the folder doesn't exist. Something like this...

Code: Select all

		  if((folderreport("items", "r", $thumbsfolder) == "") OR !(exists($thumbsfolder))) {
          $thumbsmod = $thumbsmod . "+" . $thumbsfolder . "  " . $thumbssize . "  " . $filedate . "  " . $filehash . "  " . $thumbDBsize . "<crlf>";
It's all within a foreach loop so if the conditions above are true the script builds the string for the inputselect menu one way, if not it builds it another way - without the pre-selected check marks.

Is there a way to suppress the folderreport error message that the folder does exists or another way around this? I tried to pre-condition the folderreport with another if statement such that if the folder doesn't exists the folderreport wouldn't be accomplished but as you know, XY still tries to run folderreport and gives the error. Once again, I'm probably missing something obvious or a better method. Thanks
Ken

highend
Posts: 14953
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Determine if a folder does not exists OR it has no conte

Post by highend »

No time atm but at least this logic works:

Code: Select all

    $thumbsfolder = "<path to your folder>";
    if (exists($thumbsfolder) == 2)  {
        if (listfolder($thumbsfolder) == "") {
            msg "folder exists but has no content...";
        } else {
            msg "folder exists and has content...";
        }
    } elseif (exists($thumbsfolder) == 0) {
        msg "folder does not exist...";
    }
One of my scripts helped you out? Please donate via Paypal

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

Thanks highend, it looks like there is no way to combine 2 nested "if" statements (to find out if the folder has contents) and an "OR" (to determine if the folder exists) such that if either one of those conditions is true, one action is done and if not true a different action is done. Like you said the logic you provided is correct. I ended up going with something like this.

Code: Select all

  foreach($dat2file, $dat2, "<crlf>") {
	  $f_check = "";
     $filehash = getpathcomponent($dat2file, "base");      //gets the base file name which is the "hash"
     $dat2info = readfile("$dat2file", "b", 75, , 17);     //reads each thumbnail ".dat2" file for the folder and thumbnail size
     $thumbDBsize = formatbytes(filesize(replace("$dat2file", "dat2", "dbits")), MB);   //obtain size of cache, "dbit" file size
     $thumbsfolder = gettoken($dat2info, 1, "*", "t");     //extract the folder
     $thumbssize = gettoken($dat2info, "2", "*", "t");     //extract the thumbnail size
     $filedate = property("#3", "$dat2file");              //obtains the file date
		if (exists($thumbsfolder) == "2") {
		    if(listfolder($thumbsfolder) == "") {$f_check = "1"}
		} elseif (exists($thumbsfolder) == "0") {$f_check = "1"}
		    
    if ($f_check == "1") {
		$thumbsmod = $thumbsmod . "+" . $thumbsfolder . "  " . $thumbssize . "  " . $filedate . "  " . $filehash . "  " . $thumbDBsize . "<crlf>";
          $thumbssync = $thumbssync . "+" . $thumbsfolder . "|" . $thumbssize . "|" . $filehash . "<crlf>"; $no_longer_exist = "1";}
		  
    else {$thumbsmod = $thumbsmod . $thumbsfolder . "  " . $thumbssize . "  " . $filedate . "  " . $filehash . "  " . $thumbDBsize . "<crlf>";
          $thumbssync = $thumbssync . $thumbsfolder . "|" . $thumbssize . "|" . $filehash . "<crlf>";}
     }
It seems to be working fine though I'll test some more.

By the way, the reason I got back into this was, I found out that even if you delete all the files in a folder in which you had thumbnails, the database files "dat2" and "dbits" will still remain even after regular refreshing and thumbnail refreshing. I realized that if you had sub folders the DB may still exist but it shouldn't if you have no files or subs. I knew that the database survived for deleted folders but I wanted to clean up this new situation as well (i.e., delete the DB files for empty folders).
Thanks once again,
Ken

highend
Posts: 14953
Joined: 06 Feb 2011 00:33
Location: Win Server 2022 @100%

Re: Determine if a folder does not exists OR it has no conte

Post by highend »

So, more time...

Actually you can exactly do what you want to do with (but be careful, reporting folders with xxx thousand files on a hdd can be time consuming...) so this serves more as a proof of concept:

Code: Select all

    $thumbsfolder = "D:\test";
    if (report("{count}", $thumbsfolder) == "" || report("{count}", $thumbsfolder) == 0) {
        msg "folder does not exists or exists but has no content...";
    }
== "" -> Folder does not exist
== 0 -> Folder exists but has neither a file nor a folder in it

Both statements will be executed so it would be better to do it only once and just compare the contents of the variable instead.
One of my scripts helped you out? Please donate via Paypal

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Determine if a folder does not exists OR it has no conte

Post by TheQwerty »

I wanted to take a stab as well...

This is my preference because it is easier to read, follow, and has the fewest function/command calls:

Code: Select all

$exists = exists($thumbsfolder);

$f_check = ($exists == 0);
// If a folder, check if it is empty...
if ($exists == 2) {
  $f_check = (listfolder($thumbsfolder,, 32) == 0);
}
That said, if you don't mind sacrificing in favor of reducing your lines of code then you can use a ternary to get it down to two, and if you don't mind the redundant call to exists you can make it a single long line:

Code: Select all

$exists = exists($thumbsfolder);
$f_check = ($exists == 2) ? (listfolder($thumbsfolder,,32) == 0) : ($exists == 0);
// shorter still:
$f_check = (exists($thumbsfolder) == 2) ? (listfolder($thumbsfolder,,32) == 0) : (exists($thumbsfolder) == 0);
In any event I prefer listfolder over report since it is non-recursive and if I'm not going to use the results I'd rather just have the count of items.*



In other news I just learned that unlike the boolean operators XY does short-circuit ternary. Which means highend's example is actually better off as follows because it will skip the second report when the first returns an empty string:

Code: Select all

$thumbsfolder = input(,,"C:\test");
    if ((report("{count}", $thumbsfolder) == "") ? true : (report("{count}", $thumbsfolder) == 0)) {
        msg "folder does not exists or exists but has no content...";
    }
Unless you are a fan of nice and legible code.** :whistle:


EDIT:
* I realize you can use report to get the Count - this was to explain why I included the 32 flag.
** I meant the use of ternary is ugly here not the reports themselves.

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

Hi highend, the $thumbsfolder is obtained within a foreach loop, pulling it out of each and every thumb dat2 file, of which there could be hundreds. It also looks like the report doesn't work if the folder is backslashed which it is within the dat2 file so I'd have to strip it. More importantly, I don't need or want the check to see if the folder had files or sub folders to be recursive so report would end up taking more time. I did find out I could combine the "exists" statement for the check if the folder exists with the other report check for content like this

Code: Select all

if (exists($thumbsfolder) != "2" || report("{count}", $thumbsfolder) == 0) {
I may have to run a few speed checks since we are talking a number of files in <xythumbs> essentially <XYthumbs> divided by 2. Thanks, Ken

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

Thanks TheQwerty for the additional suggestions. I do favor using listfolder since it is non-recursive. My first attempts were with folderreport("list"...in the first post since it is also non-recursive and I suppose could be used in your examples. I've got quite a lot to learn from | digest | test tonight and I do have to review ternary conditionals.
Thanks again,
Ken

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

Hi TheQwerty, I'm not sure if the first 2 examples you provided using listfolder will give me the results I need which is the same result if the folder is empty OR the folder does not exist and a different result if the folder contains files. I want to perform the same script actions if either the folder does not exists or if the folder is empty. I ran your 2 examples (one with the if / condition, the other with ternary on 3 different folder conditions with the same results. See below.

Code: Select all

E:\5 - folder exists but has no files or subs in it
$exists = 2,  $f_check = 0
E:\7 - folder does not exist
$exists = 0,  $f_check = 1
E:\3 - folder exists with files in it
$exists = 2,  $f_check = 0
I'm not sure what I can do with that result but maybe I'm missing something. :eh:
Thanks,
Ken

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Determine if a folder does not exists OR it has no conte

Post by TheQwerty »

:oops: You're right it doesn't work as expected.
Remove the 32-flag from the listfolder, check if its result == '' instead of zero, and that should be correct now.


Don, surely it is a bug that ListFolder returns an empty string instead of zero when using the count flag (32) with an empty folder, right? ;)

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

I ran the tests again using no parameters in listfolder other than the $thumbsfolder and the results were the same. So for this to work properly, you were relying on listfolder returning a "0" not a "" for situation where the folder exists but has no files ("E:\5" in my example). It does seem odd that a return count (32) would return "" in lieu of "0". I tried using $f_check = (folderreport("items", "r", $thumbsfolder) == "0");with the same result.

Obviously , the next thing I tried was using "" instead of "0". I used it with both listfolder and folderrreport and both returned consistent results. If the folder existed but was empty or it did not exist (E:\5 and E:\7 in the examples above) the $f_check was "1". If the folder has files and/or subs (E:\3), the results were $f_check = "0". So I suppose I couldd use that... if ($f_check == "1") { do this } else {do something else}. Do you see any issues with that? Though it's probably not that much different than what I had in my second post just worded differently.
Thanks, Ken

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Determine if a folder does not exists OR it has no conte

Post by TheQwerty »

klownboy wrote:So for this to work properly, you were relying on listfolder returning a "0" not a "" for situation where the folder exists but has no files
Yes... it was rather foolish of me to believe that if I ask for the count I'd always get the count and not an empty string.

Though since XY treats '' and 0 as false we can really change our test:

Code: Select all

"_check"
  Global $thumbsfolder;
  $exists = exists($thumbsfolder);

  $f_check = ($exists == 0);
  // If a folder, check if it is empty...
  if ($exists == 2) {
    $f_check = ! listfolder($thumbsfolder);
  }
  $thumbsfolder = "E: $exists - F: $f_check - $thumbsfolder";

"Test"
  Global $thumbsfolder;

  $result = '';
  foreach($thumbsfolder, <<<PATHS
C:\
C:\test\
C:\test\empty
C:\test\fake
C:\test\file.txt
C:\test\fakefile.txt
PATHS
  , "<crlf>") {
    Sub '_check';
    $result = $result . $thumbsfolder . "<crlf>";
  }

  Text $result;
With '! listfolder(...)' we now don't care if the count flag is used or not because XY will evaluate it as a boolean when not-ing it. This works because XY treats '' and 0 as false and non-empty strings as true in conditionals.


Going back to your other example we can do some re-formatting and probably make it:

Code: Select all

foreach($dat2file, $dat2, "<crlf>") {

	$filehash = getpathcomponent($dat2file, "base");      //gets the base file name which is the "hash"
	$dat2info = readfile("$dat2file", "b", 75, , 17);     //reads each thumbnail ".dat2" file for the folder and thumbnail size
	$thumbDBsize = formatbytes(filesize(replace("$dat2file", "dat2", "dbits")), MB);   //obtain size of cache, "dbit" file size
	$thumbsfolder = gettoken($dat2info, 1, "*", "t");     //extract the folder
	$thumbssize = gettoken($dat2info, "2", "*", "t");     //extract the thumbnail size
	$filedate = property("#3", "$dat2file");              //obtains the file date

	// Determine if the path is non-existent / present.
	$exists = exists($thumbsfolder);
	$no_longer_exist = ($exists == 0);

	// Also treat empty folders as non-existent.
	if ($exists == 2) {
		$no_longer_exist = ! listfolder($thumbsfolder);
	}
	//$thumbsfolder = "E: $exists - F: $no_longer_exist - $thumbsfolder";

	// If item no longer exists - check it!
	$f_check = $no_longer_exist ? '+' : '';

	$thumbsmod = $thumbsmod . $f_check . $thumbsfolder . "  " . $thumbssize . "  " . $filedate . "  " . $filehash . "  " . $thumbDBsize . "<crlf>";
	$thumbssync = $thumbssync . $f_check . $thumbsfolder . "|" . $thumbssize . "|" . $filehash . "<crlf>";}
}
Hopefully, I didn't make any mistakes or incorrect assumptions this time, but if so please forgive me for it is early and I haven't gotten my first dose of caffeine yet. ;)

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

Hi TheQwerty, I real life tested with folders. I created one folder, loaded it with pics and then thumbnail refreshed and then deleted the folder. I did the same with another folder but instead of deleting the folder I only deleted the files. As expected, the thumb DB files for both folders were still in <xythumbs>. Ran the script and everything looked fine (i.e., the checks were present for those folders) and ran properly though I'll test some more.

I had no problem following the logic through. I like the way you used the ternary conditional to simplify the string build-up for each case. The only thing I couldn't follow was your comment //$thumbsfolder = "E: $exists - F: $no_longer_exist - $thumbsfolder"; :eh:
TheQwerty wrote:Yes... it was rather foolish of me to believe that if I ask for the count I'd always get the count and not an empty string.
No, I think you rightly so should have expected it. Should I note this under possible bugs or hopefully Don will respond to your comment above?
Thanks again,
Ken

Edit: I just realized I was using the very same $no_longer_exist = "1" in my script as a flag for another section of the script. It was set to "1" if there were any folders that either didn't exist or existed but are now empty (see above)...used as a flag for the user that if he was trying to "rebuild" thumb cache he should first eliminate folders that don't exist or have no files. Now the variable is changing with each folder so it will be whatever the last folder is. So, it may end up "0" or "" instead of "1". I'll have to set an additional flag to "1" if $no_longer_exist is ever set to "1";

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Determine if a folder does not exists OR it has no conte

Post by TheQwerty »

klownboy wrote:Edit: I just realized I was using the very same $no_longer_exist = "1" in my script as a flag for another section of the script.
I was afraid that might be the case... Then I suggest renaming all instances in the above code to a different variable or just reuse $f_check and then replacing

Code: Select all

$f_check = $no_longer_exist ? '+' : '';
with

Code: Select all

if ($f_check) {
  $no_longer_exist = true;
  $f_check = '+';
} else {
  $f_check = '';
}
That comment was just no longer needed code from the debug version.

klownboy
Posts: 4462
Joined: 28 Feb 2012 19:27
Location: Windows 11, 25H2 Build 26200.8737 at 100% 2560x1440

Re: Determine if a folder does not exists OR it has no conte

Post by klownboy »

Thanks The Qwerty. I had already went ahead and added to the end of your existing ternary conditional statement like so...

Code: Select all

$check = $no_longer_exist ? '+' : '';
if($check == '+') {$folder_check = "1"};
The $check now is the same as the old $f_check (just a name change) and $folder_check is the flag for the other section of the script. Though maybe mine is more work since it has an additional "If" statement along with the ternary whereas your example is working from one If statement. I did try your replacement though and everything end up being checked. Is the first line "if ($f_check) { " going to work properly when $f_check has not been established? Isn't it ''?

TheQwerty
Posts: 4373
Joined: 03 Aug 2007 22:30

Re: Determine if a folder does not exists OR it has no conte

Post by TheQwerty »

klownboy wrote:Is the first line "if ($f_check) { " going to work properly when $f_check has not been established? Isn't it ''?
That suggestion went hand-in-hand with reverting back to using $f_check instead of $no_longer_exist. Thus you'd need to change the previous lines to:

Code: Select all

   $f_check = ($exists == 0);

   // Also treat empty folders as non-existent.
   if ($exists == 2) {
      $f_check = ! listfolder($thumbsfolder);
   }

   // If item no longer exists - check it!
  if ($f_check) {
    $f_check = '+';
    $no_longer_exist = true;
  } else {
    $f_check = '';
  }
At which point there is no instance of $f_check being used before set.

Post Reply