CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Advanced:
Simple tricks for deleting directories/files

 



Michael
Deleted

May 26, 2000, 10:06 PM

Post #1 of 7 (2858 views)
Simple tricks for deleting directories/files Can't Post

Just throwing out a request to anyone who knows an easy/simple way to delete dirs with nested subdirs and files
It would be one directory with multiple subdirs (also with subdirs) and dozens of files each.

Anyone?



japhy
Enthusiast / Moderator

May 26, 2000, 10:20 PM

Post #2 of 7 (2858 views)
Re: Simple tricks for deleting directories/files [In reply to] Can't Post

Use the standard File::Path module.

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


use File::Path;
rmtree($dir);
# or
rmtree(\@array_of_dirs);
</pre><HR></BLOCKQUOTE>

Read the File::Path documentation (perldoc File::Path).

[This message has been edited by japhy (edited 05-27-2000).]


Michael
Deleted

May 27, 2000, 12:27 PM

Post #3 of 7 (2858 views)
Re: Simple tricks for deleting directories/files [In reply to] Can't Post

Yep, I ended up doing this:

sub Delete_Stuff {
@filetype = ('*.*');
foreach $row(@in) {

($Name, $Value) = split ("=", $row);
$Name = &decodeURL($Name);
$Value = &decodeURL($Value);

($Trash, $ForumNumber) = split(/\|\|\|/, $Name);
push (@AdjustForums, $ForumNumber);
print "$Trash, $ForumNumber, $Value <br>";
if ($Trash eq "DelForum") {
$Num = $Value;
print "<br>Forum Path $ForumsPath/Forum$Num<br>";

$dir = "$ForumsPath/Forum$Num";
$days = 1;
opendir DIR, $dir or print "can't open $dir: $!<BR>";

while (defined ($file = readdir DIR)) {
next if $file eq "." or $file eq "..";

$next = "$dir/$file";
push(@files, $next);
push(@all_files, $next);

}
foreach $files(@files) {

opendir(DIR2, "$files") &#0124; &#0124; print "can't open $files: $!<BR>";

while (defined ($file2 = readdir DIR2)) {
next if $file2 eq "." or $file2 eq "..";

$next2 = "$files/$file2";
push(@files2, $next2);
push(@all_files, $next2);
}
}
foreach $files2(@files2) {

opendir(DIR3, "$files2") &#0124; &#0124; print "can't open $files2: $!<BR>";

while (defined ($file3 = readdir DIR3)) {
next if $file3 eq "." or $file3 eq "..";


$next3 = "$files2/$file3";
push(@files3, $next3);
push(@all_files, $next3);
}
}
foreach $files3(@files3) {

opendir(DIR3, "$files3") &#0124; &#0124; print "can't open $files3: $!<BR>";

while (defined ($file4 = readdir DIR4)) {
next if $file4 eq "." or $file3 eq "..";


$next4 = "$files3/$file4";
push(@files4, $next4);
push(@all_files, $next4);
}
}
$all_del = join("+", @all_files);
print "<BR><HR><FONT COLOR=RED><B>Found Files & Directories</B></FONT><BR>";
foreach $all_files(@all_files) {
print "$all_files<br>";
}
print "<BR><HR><FONT COLOR=RED><B>Delete Files & Directories</B></FONT><BR>";
foreach $all_files(@all_files) {
rmtree($all_files, 1, 1) or print " ! can't remove $all_files: $!<BR>";
#print "<BR>";
}
print "<BR><HR><FONT COLOR=RED><B>Delete Forum Directory</B></FONT><BR>";
chdir($ForumsPath);
rmdir($dir) or print "can't remove $dir: $!<BR><BR>";





}

}
print " $!<br>";
print "Whoa big mama.";


exit;
}

It's spaghetti code, but good enough for a rough draft. ;-) I'll optimize it later.


japhy
Enthusiast / Moderator

May 27, 2000, 2:31 PM

Post #4 of 7 (2858 views)
Re: Simple tricks for deleting directories/files [In reply to] Can't Post

It's really icky though, in the technical sense of the word. Your code expects directory structures to be of a certain depth, and treats every file as a directory and tries to open it. This solution is not scalable.

Think about how to get it done in a general matter.

1. open a directory
2. for each file:
2a. skip the file if it's . or ..
2b. if it's a directory, go to 1
2c. if it's a file, delete it
3. delete the directory

We can tell this is going to be a recursive type of operation. Let's write the pseudocode for the function.

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


func deltree {
path = arg[0]
opendir dir, path
foreach file in dir {
deltree(path/file) if file is directory
delete(path/file) if file is not directory
}
}
</pre><HR></BLOCKQUOTE>

This is simple enough to write in Perl code quickly:

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


sub deltree {
my ($path) = @_;
my $file;
local *DIR;
opendir DIR, $path or warn("can't read $path: $!") and return;
while (defined($file = readdir DIR)) {
next if $file eq '.' or $file eq '..';
if (-d "$path/$file") {
deltree("$path/$file");
}
else {
unlink "$path/$file" or warn "can't unlink $path/$file: $!";
}
}
closedir DIR;
rmdir $path or warn "can't rmdir $path: $!";
}
</pre><HR></BLOCKQUOTE>

Try that out. If there's something you don't understand about it, ask, and I'll explain.


Michael
Deleted

May 27, 2000, 4:42 PM

Post #5 of 7 (2858 views)
Re: Simple tricks for deleting directories/files [In reply to] Can't Post

Yes, I see what you've done. Nice.
The code I posted was reporting the files and directories as it went, (I already knew how deep it needed to go.) I was having permission problems and a couple dirs were being stubborn.
I've got that fixed, and simplified the code down to three lines. ;-)
However, one thing I found, and the main reason why I wasn't detecting file/dir types was the -d switch was not returning a true under any case! Neither -f or -d returned true values.
I'm working on an NT server, with all UNIX/LINUX experience, so small differences are expected, but that took me by surprise.
Any ideas?


japhy
Enthusiast / Moderator

May 27, 2000, 6:17 PM

Post #6 of 7 (2858 views)
Re: Simple tricks for deleting directories/files [In reply to] Can't Post

The reason none of the files show up as a file or a directory is because readdir() returns the NAME of the file, not the PATH to the file. You need to prepend the path to the file (like is shown in my code).

<BLOCKQUOTE><font size="1" face="Arial,Helvetica,sans serif">code:</font><HR>


opendir DIR, $path;
while (defined($file = readdir DIR)) {
if (-d "$path/$file") { ... }
else { ... }
}
closedir DIR;
</pre><HR></BLOCKQUOTE>


Michael
Deleted

May 27, 2000, 9:42 PM

Post #7 of 7 (2858 views)
Re: Simple tricks for deleting directories/files [In reply to] Can't Post

Aaah, okay, Thanks.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives