Forum: Ruby Test if Directory is Empty

8dbe866cad132bf588ee4f54a03bc1de?d=identicon&s=25 lroland@gmail.com (Guest)
on 2006-10-16 12:42
(Received via mailing list)
Hi all

I browsed through the FileUtils and Dir documentation and found no
obvious way to test if a directory exists and is empty. Various hacks
can be used (like checking file count and size, testing if the
directory can be deleted..) but they all left me wondering if i some
how missed a Dir.isEmpty? like method ?

So in short is there a real Ruby way of telling whether a directory if
empty
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2006-10-16 12:52
(Received via mailing list)
lroland@gmail.com wrote:
> Hi all
>
> I browsed through the FileUtils and Dir documentation and found no
> obvious way to test if a directory exists and is empty. Various hacks
> can be used (like checking file count and size, testing if the
> directory can be deleted..) but they all left me wondering if i some
> how missed a Dir.isEmpty? like method ?
>
> So in short is there a real Ruby way of telling whether a directory if
> empty

if Dir["/foo/bar/*"].empty?

Regards,

Dan
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-10-16 16:21
(Received via mailing list)
On Mon, 16 Oct 2006, Daniel Berger wrote:

>> empty
>
> if Dir["/foo/bar/*"].empty?

that'll crawl if a directory is huge though... i've used this


   d = "the_dir"

   empty =
     catch("empty"){
       Dir.glob("#{ d }/*"){ throw "empty", false }  # if we find any
file return false
       Dir.glob("#{ d }/.*"){ throw "empty", false } # if we find any
dotfile/hidden return false
       throw "empty", true                           # otherwise return
true
     }

which someone will probably compact... note that it returns false when
the
first file/dotfile is found.

cheers.

-a
F1d6cc2b735bfd82c8773172da2aeab9?d=identicon&s=25 Nobuyoshi Nakada (Guest)
on 2006-10-16 18:28
(Received via mailing list)
Hi,

At Mon, 16 Oct 2006 23:19:30 +0900,
ara.t.howard@noaa.gov wrote in [ruby-talk:220018]:
> which someone will probably compact... note that it returns false when the
> first file/dotfile is found.

  !Dir.foreach(dirname) {|n| break true unless /\A\.\.?\z/ =~ n}
  !Dir.enum_for(:foreach, dirname).any? {|n| /\A\.\.?\z/ !~ n}
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-10-16 18:45
(Received via mailing list)
On Tue, 17 Oct 2006, Nobuyoshi Nakada wrote:

> Hi,
>
> At Mon, 16 Oct 2006 23:19:30 +0900,
> ara.t.howard@noaa.gov wrote in [ruby-talk:220018]:
>> which someone will probably compact... note that it returns false when the
>> first file/dotfile is found.
>
>  !Dir.foreach(dirname) {|n| break true unless /\A\.\.?\z/ =~ n}
>  !Dir.enum_for(:foreach, dirname).any? {|n| /\A\.\.?\z/ !~ n}

nice.  double negation is always good!

-a
5d8990b757a1305f8e9100e9e4e5073d?d=identicon&s=25 WATANABE Hirofumi (Guest)
on 2006-10-16 18:53
(Received via mailing list)
Hi,

Nobuyoshi Nakada <nobu@ruby-lang.org> writes:

> At Mon, 16 Oct 2006 23:19:30 +0900,
> ara.t.howard@noaa.gov wrote in [ruby-talk:220018]:
> > which someone will probably compact... note that it returns false when the
> > first file/dotfile is found.
>
>   !Dir.foreach(dirname) {|n| break true unless /\A\.\.?\z/ =~ n}
>   !Dir.enum_for(:foreach, dirname).any? {|n| /\A\.\.?\z/ !~ n}

Dir.entries(dirname).join == "..."
23172b6630dc631a134c9bad2fec2a39?d=identicon&s=25 ChrisH (Guest)
on 2006-10-16 19:07
(Received via mailing list)
lroland@gmail.com wrote:
>
>
> --
> Lars Roland

You could try:

class Dir
   def Dir.isEmpty?(path)
      Dir.entries(path) == [".", ".."]
   end
end

Cheers
Chris
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-10-16 19:21
(Received via mailing list)
WATANABE Hirofumi wrote:
> Dir.entries(dirname).join == "..."

Dir.entries(dirname).size == 2

But this still has the disadvantage that Ara mentioned for huge dirs...
C5d7ff9e450250329d01b7c2ca27dcaf?d=identicon&s=25 John Turner (Guest)
on 2006-10-16 21:22
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
>>>
>   empty =
>
> cheers.
>
> -a

Not sure about using throw to return values there...  Also, won't the
"Dir.glob("#{ d }/.*")" return [".", ".."] (well, pass "." to the block)
and break this?

How about:

def isEmpty?(dir)
   Dir.glob("#{dir}/*", File::FNM_DOTMATCH) do |f|
     return false unless f =~ /\.\.?/
   end
   return true
end
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (Guest)
on 2006-10-17 00:42
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> >>
> >> So in short is there a real Ruby way of telling whether a directory if
> >> empty
> >
> > if Dir["/foo/bar/*"].empty?
>
> that'll crawl if a directory is huge though

<snip>

True.  Oh, look - Windows has a PathIsDirectoryEmpty() function. :)

win32-dir 0.3.1 coming soon....

Thanks,

Dan
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-10-17 05:57
(Received via mailing list)
On Tue, 17 Oct 2006, John Turner wrote:


not sure what you mean there - that's the correct usage... read the ri
for
catch.

> end
yes.  that's definitely better...

that regex is deadly though:

   harp:~ > irb
   irb(main):001:0> "this is a file ..." =~ /\.\.?/ ? true : false
   => true

refining some of the ideas in the thread:


     harp:~ > cat a.rb
     class Dir
       def empty?
         Dir.glob("#{ path }/*", File::FNM_DOTMATCH) do |e|
           return false unless %w( . .. ).include?(File::basename(e))
         end
         return true
       end
       def self.empty? path
         new(path).empty?
       end
     end

     d = Dir.new '/tmp'
     p d.empty?

     require 'fileutils'
     FileUtils.rm_f 'empty'
     FileUtils.mkdir_p 'empty'
     p(Dir.empty?('empty'))


     harp:~ > ruby a.rb
     false
     true


now we can begin the discussion on how to use such a method - since
nearly any
code that did would have a race condition!  ;-)


-a
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.