ScriptSpot

Forum topic · General Scripting

"isFolderEmpty" function

By barigazy · 2013-12-29

Description

Does anyone know what is the best way to check if some directory is empty or not.
This fn need to be very "light" for efficient use within a for-loop. I already have a solution but I'm curious if there better solution.
This fn need to have only one argument which represent directory path.
Something like this

fn isFolderEmpty folder:/*path String*/ = ( )

Comments (10)

I got some errors.

Rodman · 2013-12-30


#Struct:dirOps(
  sioSOpt:<data>; Private,
  sioDir:<data>; Private,
  getFullPathBy:<fn>; Public,
  isFolderEmpty:<fn>; Public)
(dirOps)
#("c:\test", "c:\myfiles", "d:\works", "e:\images", "f:\proxyfiles")
-- Error occurred in isFolderEmpty(); filename: C:\Users\Ranch\Desktop\isFolderEmpty.ms; position: 262; line: 9
--  Frame:
--   folder: "f:\proxyfiles"
--   patt: "*.max"
--   called in i loop; filename: C:\Users\Ranch\Desktop\isFolderEmpty.ms; position: 719; line: 20
--  Frame:
--   i: 5
-- Runtime error: dotNet runtime exception: Could not find a part of the path 'f:\proxyfiles\'.
-- Error occurred in d loop; filename: C:\Users\Ranch\Desktop\isFolderEmpty.ms; position: 436; line: 14
--  Frame:
--   d: "c:\test"
--   a: undefined
--   called in getFullPathBy(); filename: C:\Users\Ranch\Desktop\isFolderEmpty.ms; position: 512; line: 14
--  Frame:
--   notFound: true
--   dirs: #("c:\test", "c:\myfiles", "d:\works", "e:\images", "f:\proxyfiles")
--   fullfilepath: ""
--   filename: "vray_test_scene.max"
-- Runtime error: dotNet runtime exception: Could not find a part of the path 'c:\test\'.

I'm currently working on 3ds Max 2012.

barigazy · 2013-12-30

I corrected code below. I put only one real directory "c:\temp".
U need to change directory list and filename and then make a test

.

Rodman · 2013-12-30

It works now. You made a simple mistake with the boolean value.


if not (sioDir.Exists folder) then on else

I prefer to put all inside the parenthesis of the function, it makes thing clearer to verify.

barigazy · 2013-12-30

I purposely made this mistake to see if you are ready for first assignment. :)
Ok. You passed the test :)
Wait for my mail.

:)

Rodman · 2013-12-29


fn isFolderEmpty folder: =
(
	((dotnetclass "System.IO.Directory").GetFiles folder).count == 0
)

isFolderEmpty folder:"c:\\test"

barigazy · 2013-12-29

You are close.Nice try.
What if you have inside "c:\\test" directory only one folder (not files) and that folder have another folder and so on where last folder only contains files.
Also if you put this fn inside for-loop you will create dotnet class over and over again. That's not so eficient. Try again

;)

;)

Rodman · 2013-12-29


fn isFolderEmpty folder: =
(
	((dotNetClass "System.IO.Directory").GetFiles folder "*" (dotNetClass "System.IO.SearchOption").AllDirectories).count == 0
)

isFolderEmpty folder:"c:\\test"

barigazy · 2013-12-29

Ok that is even more close but still just think about this:
What if you have something like this


arr = #("c:\\test", "c:\\myfiles", "d:\\works", "e:\\images", "f:\\proxyfiles")
for i = arr.count to 1 by -1 where (isFolderEmpty folder:arr[i]) do deleteItem arr i

You will then also create two .net classes over and over again

.

Rodman · 2013-12-29

I'm not familiar with memory efficiency. I'll tell you later if I have a better function, but for now, that's all I can give.

Let's pray for the divine answer. :D

barigazy · 2013-12-30

You deserve to see the answer :)
You can extend this struct but for now you can also check if specific file is inside folder using different pattern. Also U need to check if directory exists.

struct dirOps
(
private
sioDir = dotNetClass "System.IO.Directory",
sioSOpt = (dotNetClass "System.IO.SearchOption").AllDirectories,
public
fn isFolderEmpty folder: patt: = if not (sioDir.Exists folder) then on else
(
(sioDir.GetFiles folder patt sioSOpt).count == 0
),
fn getFullPathBy dirs: filename: =
(
local fullfilepath = "", notFound = on
for d in dirs while notFound do (if (a=sioDir.GetFiles d ("*"+filename) sioSOpt).count > 0 do fullfilepath = a[1] ; notFound = off)
fullfilepath
)
)
dirFilter = dirOps()
arr = #("c:\\temp", "c:\\myfiles", "c:\\works", "c:\\images", "c:\\proxyfiles")
for i = arr.count to 1 by -1 where (dirFilter.isFolderEmpty folder:arr[i] patt:"*.max") do deleteItem arr i
-- i filled "arr" with wirtual directory paths
-- if you use real directories (paths) then u can try to find full path of some filename
if arr.count != 0 do dirFilter.getFullPathBy dirs:arr filename:"vray_test_scene.max"