johfiner has asked for the wisdom of the Perl Monks concerning the following question:

i'm writing a script to organize all of my mp3s for me, and i'm having problems getting the script to rename my files.

it will work for some files once, but not twice, and will randomly work on other files. when it doesn't work, it always says "permission denied." for example, i was able to rename "e.mp3" to "1. animal collective - something.mp3" and then that file to "2. animal collective - bonfire.mp3", but now i can't rename it to anything. i was also able to rename "g.mp3" to "j.mp3" but i couldn't rename "g.mp3" to "1. animal collective - something.mp3".

i've made sure these files aren't in use and there is no chance for duplicate file names....

i'm stumped!

here's my rename code:
sub renamefiles { my ($mp3file, $mp3dir) = @_; my @mp3file = @$mp3file; my @mp3dir = @$mp3dir; my $i=0; foreach my $e (@mp3file) { $curfile="$mp3dir[$i]\\$mp3file[$i]"; chomp($curfile); my $mp3 = MP3::Tag->new($curfile); my ($title, $track, $artist) = $mp3->autoinfo(); print ("$curfile: $track. $artist - $title.mp3\n"); print ("|$mp3dir[$i]::$mp3file[$i]|\n"); chdir($mp3dir[$i]); rename("g.mp3", "j.mp3") or die "$!"; $i++; } }

Replies are listed 'Best First'.
Re: rename works sporadically on windows??
by bart (Canon) on Feb 22, 2006 at 09:04 UTC
    I'm wondering if MP3::Tag could still have that file open. In which case, Windows won't allow you to rename the file.

    Ah, got it: MP3::Tag has a close() method. Just call it before you rename the file.

    $mp3->close;
      ahh i could kiss you two!

      thank you so much for that info, i never would've figured this out myself... i have a pretty rudimentary knowledge of perl, and on top of that i haven't touched it in 4 month

      so yeah thanks, should be able to complete this script tonight, saving me hours and hours on sorting music!

        On windows it helps to check $^E
        C:\>echo >2 C:\>perl -e"open IN, 2 or die $!; warn 'opened';rename 2, 2222 or die +$!,$/,$^E" opened at -e line 1. Permission denied The process cannot access the file because it is being used by another + process at -e line 1.

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.

Re: rename works sporadically on windows??
by Corion (Patriarch) on Feb 22, 2006 at 08:59 UTC

    My guess is that the file is open. MP3::Tag has different handlers for ID3v1 and ID3v2 formats, so my guess is that some of the "unrenamable" files have ID3v2-style tags and are kept open. Permission denied usually means that a file has been opened by a program and not yet closed, even if it is your own program.

    You can try to close the file by discarding your $mp3 variable before trying to rename. Update: See bart's post below for the ->close method, which is likely less confusing than the discarding of the object just to close the filenhandle.

    ... my ($title, $track, $artist); { my $mp3 = MP3::Tag->new($curfile) or die "Didn't get an mp3 tag from '$curfile'"; ($title, $track, $artist) = $mp3->autoinfo(); }; ...

    As an aside, rename() also takes directory names, so you don't need to chdir(). Have a look at File::Basename and/or File::Spec to get convenient pathname manipulation tools:

    my $newname = File::Spec->catfile($mp3dir[$i],"$track. $artist - +$title.mp3"); my $oldname = File::Spec->catfile($mp3dir[$i],$mp3file[$i]); rename($oldname, $newname) or die "Couldn't rename '$oldname' to '$newname': $!";