Delete a directory safely (only when it's empty)

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Delete a directory safely (only when it's empty)

Post by Mistrel »

This is a special case for DeleteDirectory. It only applies to the directory itself (no use of Pattern$ or Mode parameters), and will only succeed if the directory is empty.

Code: Select all

;/ Only delete the directory is it is empty
Procedure DeleteDirectorySafely(Path.s)
  Protected PathID
  Protected Result
  Protected EntryName.s
  Protected PathNotEmpty
  Protected i
  
  If Not FileSize(Path.s)=-2
    ProcedureReturn #False
  EndIf
  
  PathID=ExamineDirectory(#PB_Any,Path.s,"")
  If PathID
    For i=1 To 3
      Result=NextDirectoryEntry(PathID)
      EntryName.s=DirectoryEntryName(PathID)
      If Result And EntryName.s<>"." And EntryName.s<>".."
        PathNotEmpty=#True
      EndIf
    Next i
    
    If Not PathNotEmpty
      FinishDirectory(PathID)
      Result=DeleteDirectory(Path.s,"")
      ProcedureReturn Result
    EndIf
    
    FinishDirectory(PathID)
  EndIf
  
  ProcedureReturn #False
EndProcedure
Last edited by Mistrel on Sat Oct 09, 2010 8:12 am, edited 1 time in total.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Delete a directory safely (only when it's empty)

Post by PB »

Your solution is cross-platform, which is good. But I just want
to add that for Windows only, you can use this API call instead,
which won't delete the directory if it contains any files:

Code: Select all

RemoveDirectory_(dir$)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Flower
User
User
Posts: 22
Joined: Fri Jan 08, 2010 8:05 am
Location: United States

Re: Delete a directory safely (only when it's empty)

Post by Flower »

Code: Select all

Size.q = DirectoryEntrySize(#Directory)
If(Size > 2)
  ProcedureReturn
EndIf
I guess this will also work. :mrgreen:
Registered PureBasic user since 4.50
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Delete a directory safely (only when it's empty)

Post by Mistrel »

Yes but what if the file is larger than 9223372036854775808 bytes? I mean, surely there will be a day where we might encounter an 8 exabyte file. :wink:

Code: Select all

RemoveDirectory_(dir$)
Thanks for the tip, PB. I try to avoid using Win32 for the basic stuff I may need elsewhere.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Delete a directory safely (only when it's empty)

Post by PB »

> I try to avoid using Win32 for the basic stuff I may need elsewhere

I know. Just pointing it out for folks who code for Windows only, like myself.
I'll always take a single API call over a dedicated procedure any time. :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Delete a directory safely (only when it's empty)

Post by Mistrel »

Fixed a minor bug. I forgot to close the directory before attempting to delete it! :shock:

Code: Select all

Size.q = DirectoryEntrySize(#Directory)
If(Size > 2)
  ProcedureReturn
EndIf
A directory may be full of zero-byte files. You really do need to examine it closely.
Flower
User
User
Posts: 22
Joined: Fri Jan 08, 2010 8:05 am
Location: United States

Re: Delete a directory safely (only when it's empty)

Post by Flower »

Well, my bad. DirectoryEntrySize does not return the number of files in the directory. Guess we have to use FindFirstFile / FindNextFile ... :cry:
Registered PureBasic user since 4.50
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Delete a directory safely (only when it's empty)

Post by Trond »

What if you examine the directory and find it empty, then some program creates a file there just before your program reaches the line with DeleteDirectory()?
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Delete a directory safely (only when it's empty)

Post by Mistrel »

Trond wrote:What if you examine the directory and find it empty, then some program creates a file there just before your program reaches the line with DeleteDirectory()?
The world will explode! :shock:

Actually, during the normal course of my program I might create a temporary folder, do some stuff in it, delete everything I wrote to it, and then finally delete the folder. The whole point of this function is just a sanity check to me to make sure I don't accidentally delete "C:\Program Files (x86)", "C:\Windows", or something else really dumb like that if I made a mistake somewhere when resolving the target path.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Delete a directory safely (only when it's empty)

Post by PB »

> I might create a temporary folder, do some stuff in it,
> delete everything I wrote to it, and then finally delete
> the folder

Wow, I had the same such concept in one of my apps last week!
But, rather than delete the files first, I just delete the folder that
I created, so that it deletes all the files in that step.

Here's what I use to create my temp folder:

Code: Select all

t$=GetTemporaryDirectory() : If Right(t$,1)<>"\" : t$+"\" : EndIf
Repeat : tmpdir$=t$+"AppName"+Str(Random(99999999))+"\" : Until FileSize(tmpdir$)<>-2
If MakeSureDirectoryPathExists_(tmpdir$)=0 : End : Endif
So it creates a randomly-numbered folder inside the PC's official temp
folder, and checks to ensure the new folder doesn't already exist. If
it doesn't, then it becomes my app's folder as far as I'm concerned.

To delete it later, I do this before my app quits:

Code: Select all

DeleteDirectory(GetPathPart(tmpdir$),"",#PB_FileSystem_Recursive|#PB_FileSystem_Force)
This means I don't have to delete my temp files that I created, and
I will never accidentally delete C:\Windows by mistake either.

Now, Trond will say: what if another app creates files in that random
folder? My answer: if another app can even possibly come up with my
app's name PLUS the random 8-digit number appended to it, and then
decides to write to it, then too bad when my app kills all its data! :twisted:
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: Delete a directory safely (only when it's empty)

Post by Mistrel »

I'm not as brave as you are when it comes to DeleteDirectory, PB! :o
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Delete a directory safely (only when it's empty)

Post by PB »

Why? I know that tmpdir$ is my temp folder, so it's 100% safe to delete.
It's not like tmpdir$ is magically going to become "c:\windows" by itself.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply