Page 1 of 1
deleteing a folder and everything contained in it
Posted: Fri May 18, 2007 6:50 pm
by SHX
Here is a piece of code that i started working on to get the files in a folder
Code: Select all
(define (getfilesinfolder z) ( map (fn (a) (append z a ) )(replace ".." (replace "." (clean (fn (x) (directory? (append z x))) (directory z))))) )
Fisrt of all is this a good way of doing it?
Also, my real goal is to delete all the folders/ subfolders and files that are in a parent folder including the parent folder as well.
So I would like to set up a function that does this.
Can anyone help?
Steven
Posted: Fri May 18, 2007 9:50 pm
by cormullion
Perhaps this sort of thing. Untested - replace the innocent println statements with your own brand of destructive mayhem...
Code: Select all
(define (delete-disk-item di)
(if (directory? di)
(println "delete directory" di)
(println "delete file" di)))
(define (walk-tree dir)
(dolist (di (directory dir {^[^.]}))
(if (directory? (append dir "/" di))
(walk-tree (append dir "/" di )))
(delete-disk-item (append dir "/" di))))
(walk-tree f)
(delete-disk-item f)
Edit - I don't think that works. Sorry - don't have time to find out why.. :-(
Posted: Sun May 20, 2007 9:14 pm
by Sleeper
Hi, SHX!
try this function:
Code: Select all
(define (remove-all dir)
(set 'fnames (list dir))
(set 'dirs '())
(while (not (empty? fnames))
(set 'fname (pop fnames))
(if (directory? fname)
(begin
(dolist (x (directory fname))
(if (and (!= x ".") (!= x ".."))
(push (append fname "/" x) fnames)))
(if (!= fname dir) (push fname dirs)))
(delete-file fname)))
(dolist (x dirs) (remove-dir x)))
it removes all files and subdirs in directory.
i tested it on windows xp only
edit: to remove root folder as well replace
(if (!= fname dir) (push fname dirs))
with just
(push fname dirs)
Posted: Mon May 21, 2007 6:13 am
by Sleeper
this recursive version is better
i forgot about it :)
Code: Select all
(define (remove-all root, x full)
(dolist (x (directory root))
(set 'full (append root "/" x))
(if (directory? full)
(if (and (!= x "..") (!= x "."))
(begin
(remove-all full)
(remove-dir full)))
(delete-file full))))
example:
Code: Select all
(remove-all "c:\\temp")
(remove-dir "c:\\temp")
Posted: Tue May 22, 2007 3:04 pm
by SHX
Sleeper,
Thank you for a very elegant solution.
Also, being that I am new to newlisp, this was a very good learning experience.
One question,
(define (remove-all root, x full)
Is "X" and "full" are put in the define statement to make them private variables?
Steven
Posted: Tue May 22, 2007 5:44 pm
by Sleeper
I put "x" and "full" in define statement to make them local to this function.
http://newlisp.org/CodePatterns.html#locals
Also in this case they don't pollute global namespace. In recursive functions non-local variables may cause big problems, as they are shared between all running functions.
Posted: Tue May 22, 2007 5:57 pm
by cormullion
I think that comma is cool... :-)
Code: Select all
(define (remove-all root, x full)
(println root)
(println ,)
(println x)
(println full))
(remove-all 1 2 3 4)
1
2
3
4
(println root)
(println ,)
(println x)
(println full)
nil
nil
nil
nil
Posted: Tue May 22, 2007 7:17 pm
by Sleeper
i totally agree ;D
Posted: Wed May 23, 2007 3:19 am
by rickyboy
Sleeper wrote:this recursive version is better
...
Yes! This problem screams for a recursive solution. For those about to recurse, I salute you! :-)
BTW, you don't have to shadow the variable
x by way of your function's parameter list, as
x is already locally scoped by the
dolist.
Also, the body of your function looks like a framework for a nice abstraction;
remove-all can be an instance of that abstraction:
Code: Select all
(define (walk-dir ffunc dfunc root)
"Walk a directory tree at `root' and apply `dfunc' to
directories and `ffunc' to files."
(dolist (x (directory root))
(let (full (append root "/" x))
(if (directory? full)
(when (and (!= x "..") (!= x "."))
(walk-dir ffunc dfunc full)
(dfunc full))
(ffunc full)))))
(define remove-all (currie walk-dir delete-file remove-dir))
Of course, you'll need the following handy macros.
Code: Select all
(define-macro (when)
(letex ($test (eval (args 0))
$expr (cons 'begin (1 (args))))
(if $test $expr)))
(define-macro (currie f)
(letex ($f (eval f)
$cargs (map eval (args)))
(lambda () (apply $f (append (quote $cargs) (args))))))
Posted: Wed May 23, 2007 9:57 pm
by Sleeper
you're right, i put x after comma just in case :)
good idea with currying, it may be useful
i used for different tasks similar recursive walk function (much like in python os.walk) but without curry.