Empty directory

Revision as of 02:51, 16 March 2012 by rosettacode>Xenoker (Added Ada)

Starting with a path to some directory, determine whether the directory is empty.

Task
Empty directory
You are encouraged to solve this task according to the task description, using any language you may know.

An empty directory contains no files nor subdirectories. With Unix or Windows systems, every directory contains an entry for “.” and almost every directory contains “..” (except for a root directory); an empty directory contains no other entries.

Ada

<lang Ada>with Ada.Text_IO; use Ada.Text_IO; with Ada.Directories; procedure EmptyDir is

  function Empty (path : String) return String is
     use Ada.Directories;
     result : String := "Is empty.";
     procedure check (ent : Directory_Entry_Type) is begin
        if Simple_Name (ent) /= "." and Simple_Name (ent) /= ".." then
           Empty.result := "Not empty";
        end if;
     end check;
  begin
     if not Exists (path) then return "Does not exist.";
     elsif Kind (path) /= Directory then return "Not a Directory.";
     end if;
     Search (path, "", Process => check'Access);
     return result;
  end Empty;

begin

  Put_Line (Empty ("."));
  Put_Line (Empty ("./empty"));
  Put_Line (Empty ("./emptydir.adb"));
  Put_Line (Empty ("./foobar"));

end EmptyDir;</lang>

Output:
Not empty
Is empty.
Not a Directory.
Does not exist.

C

<lang c>#include <stdio.h>

  1. include <dirent.h>
  2. include <string.h>

int dir_empty(char *path) { struct dirent *ent; int ret = 1;

DIR *d = opendir(path); if (!d) { fprintf(stderr, "%s: ", path); perror(""); return -1; }

while ((ent = readdir(d))) { if (!strcmp(ent->d_name, ".") || !(strcmp(ent->d_name, ".."))) continue; ret = 0; break; }

closedir(d); return ret; }

int main(int c, char **v) { int ret = 0, i; if (c < 2) return -1;

for (i = 1; i < c; i++) { ret = dir_empty(v[i]); if (ret >= 0) printf("%s: %sempty\n", v[i], ret ? "" : "not "); }

return 0;

}</lang>Running it:

% mkdir stuff; ./a.out /usr/ ./stuff /etc/passwd
/usr/: not empty
./stuff: empty
/etc/passwd: Not a directory

C#

<lang c#>using System; using System.IO;

class Program {

   static void Main( string[] args )
   {
       foreach ( string dir in args )
       {
           Console.WriteLine( "'{0}' {1} empty", dir, IsDirectoryEmpty( dir ) ? "is" : "is not" );
       }
   }
   private static bool IsDirectoryEmpty( string dir )
   {
       return ( Directory.GetFiles( dir ).Length == 0 &&
           Directory.GetDirectories( dir ).Length == 0 );
   }

} </lang>

Running it:

Assume c:\temp exists and is not empty, c:\temp\empty exists and is empty

c:\>IsEmptyDir c:\temp c:\temp\empty
'c:\temp' is not empty
'c:\temp\empty' is empty


CoffeeScript

<lang coffeescript> fs = require 'fs'

is_empty_dir = (dir) ->

 throw Error "#{dir} is not a dir" unless fs.statSync(dir).isDirectory()
 # readdirSync does not return . or ..
 fns = fs.readdirSync dir
 fns.length == 0

</lang>

Groovy

Solution: <lang groovy>def isDirEmpty = { dirName ->

   def dir = new File(dirName)
   dir.exists() && dir.directory && (dir.list() as List).empty

}</lang>

Test: <lang groovy>def currentDir = new File('.') def random = new Random() def subDirName = "dir${random.nextInt(100000)}" def subDir = new File(subDirName) subDir.mkdir() subDir.deleteOnExit()

assert ! isDirEmpty('.') assert isDirEmpty(subDirName)</lang>

Icon and Unicon

This example uses Unicon extensions. The 'empty' sub-directory was manually setup for this test. <lang Icon>procedure main()

  every dir := "." | "./empty" do 
     write(dir, if isdirempty(dir) then " is empty" else " is not empty")

end

procedure isdirempty(s) #: succeeds if directory s is empty (and a directory) local d,f

  if ( stat(s).mode ? ="d" ) & ( d := open(s) ) then {
        while f := read(d) do 
           if f == ("."|"..") then next else fail 
        close(d)
        return s
        }
  else stop(s," is not a directory or will not open")

end</lang>

Output:

. is not empty
./empty is empty

J

<lang j>require 'dir' empty_dir=: 0 = '/*' #@dir@,~ ]</lang>

In other words, list the contents of the directory, count how many items are in it, and test if that count was zero.

Note that 1!:0 could have been used here, instead of the dir cover.

Example, under windows, create some directories using cygwin:

<lang bash>$ mkdir /tmp/a $ touch /tmp/a/... $ mkdir /tmp/b $ mkdir /tmp/c $ mkdir /tmp/c/d</lang>

Then, testing these directories, in J:

<lang j> empty_dir 'c:/cygwin/tmp/a' 0

  empty_dir 'c:/cygwin/tmp/b'

1

  empty_dir 'c:/cygwin/tmp/c'

0</lang>

Java

Works with: Java version 7+

This method does not check that the path given is actually a directory. If a path to a normal file is given, it will throw a NullPointerException. File.listFiles() does not count the "." and ".." entries. <lang java5>import java.nio.file.Paths; //... other class code here public static boolean isEmptyDir(String dirName){

   return Paths.get(dirName).toFile().listFiles().length == 0;

}</lang>

Mathematica

<lang Mathematica>EmptyDirectoryQ[x_] := (SetDirectory[x]; If[FileNames[] == {}, True, False])

Example use: EmptyDirectoryQ["C:\\Program Files\\Wolfram Research\\Mathematica\\9"] ->True</lang>


MATLAB / Octave

<lang Matlab>

 function x = isEmptyDirectory(p)
   if isdir(p)		
     f = dir(p)
     x = length(f)>2;
   else 
     error('Error: %s is not a directory');     
   end; 
 end; 

</lang>


OCaml

<lang ocaml>let is_dir_empty d =

 Sys.readdir d = [| |]</lang>

Perl 6

<lang perl6>sub dir-is-empty ($d) { not dir $dir }</lang> The dir function returns a lazy list of filenames, excluding "." and ".." automatically. Any boolean context (in this case the not function) will do just enough work on the lazy list to determine whether there are any elements, so we don't have to count the directory entries, or even read them all into memory, if there are more than one buffer's worth.

PHP

Any improvements welcome but here is a starting point for PHP <lang php>

$dir = 'path_here';

if(is_dir($dir)){

 //scandir grabs the contents of a directory and array_diff is being used to filter out .. and .
 $list = array_diff(scandir($dir), array('..', '.'));
 //now we can just use empty to check if the variable has any contents regardless of it's type
 if(empty($list)){
   echo 'dir is empty';
 }
 else{
   echo 'dir is not empty';
 }

} else{

 echo 'not a directory';

}

</lang>

PicoLisp

<lang PicoLisp>(prinl "myDir is" (and (dir "myDir") " not") " empty")</lang> Output:

myDir is not empty

PureBasic

<lang purebasic>Procedure isDirEmpty(path$)

 If Right(path$, 1) <> "\": path$ + "\": EndIf
 Protected dirID = ExamineDirectory(#PB_Any, path$, "*.*")
 Protected result
 
 If dirID
   result = 1
   While NextDirectoryEntry(dirID)
     If DirectoryEntryType(dirID) = #PB_DirectoryEntry_File Or (DirectoryEntryName(dirID) <> "." And DirectoryEntryName(dirID) <> "..")
       result = 0
       Break
     EndIf 
   Wend 
   FinishDirectory(dirID)
 EndIf 
 ProcedureReturn result

EndProcedure

Define path$, result$

path$ = PathRequester("Choose a path", "C:\") If path$

 If isDirEmpty(path$)
   result$ = " is empty."
 Else
   result$ = " is not empty."
 EndIf 
 MessageRequester("Empty directory test", #DQUOTE$ + path$ + #DQUOTE$ + result$)

EndIf </lang> Sample output when selecting directories "L:\vv\6\" and "L:\vv\" :

"L:\vv\6\" is empty.

"L:\vv\" is not empty.

Python

Works with: Python version 2.x

<lang python>import os; if os.listdir(raw_input("directory")):

   print "not empty"

else:

   print "empty"

</lang>


Ruby

Works with: Ruby version 1.8.7

<lang ruby># Checks if a directory is empty, but raises SystemCallError

  1. if _path_ is not a directory.

def empty_dir?(path)

 not Dir.foreach(path).detect {|f| f != '.' and f != '..'}

end</lang>

If Ruby is older than 1.8.7, then Dir.foreach must take a block.

<lang ruby># Checks if a directory is empty, but raises SystemCallError

  1. if _path_ is not a directory.

def empty_dir?(path)

 Dir.foreach(path) {|f|
   return false if f != '.' and f != '..'
 }
 return true

end</lang>

Tcl

<lang tcl>proc isEmptyDir {dir} {

   # Get list of _all_ files in directory
   set filenames [glob -nocomplain -tails -directory $dir * .*]
   # Check whether list is empty (after filtering specials)
   expr {![llength [lsearch -all -not -regexp $filenames {^\.\.?$}]]}

}</lang>