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*/ = ( )
Forum topic · General Scripting
"isFolderEmpty" function
By barigazy · 2013-12-29
Description
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"