Perl:dirhandle的坏符号

时间:2014-09-14 12:17:46

标签: windows perl rename dir

这是我的代码:

opendir(DIR, $directoryPath) or die "Cant open $directoryPath$!";
my @files = readdir(DIR); #Array of file names
closedir (DIR) or die "Cant close $directoryPath$!";

我正在使用@files在目录中创建一个文件名数组,以便稍后在程序中重命名。

问题是:

  1. 我在封闭线上收到错误“dirhandle的坏符号”。
  2. 如果我没有关闭以避免这种情况,我无权更改文件名(我正在使用Windows)。
  3. 我尝试了另一种重命名文件的方法(下面),通过以不同的方式在dirhandles中重命名文件来尝试不同的问题解决方案,但这只是重复了权限错误。

    opendir(DIR, $directoryPath) or die "Cant open $directoryPath$!";
    while( (my $filename = readdir(DIR)))
    {
        rename($filename, $nFileName . $i) or die "Cant rename file $filename$!";
        i++;
    }
    closedir (DIR) or die "Cant close $directoryPath$!";
    
  4. 从快速的研究中我认为权限错误是一个Windows安全功能,因此您无法在打开时编辑文件,但我无法找到足够简单的解决方案让我理解。

    对第1点或第3点的回答是可取的,但对第2点的回答也很有用。

    第1点和第2点中使用的完整代码

    use 5.16.3;
    use strict;
    
    print "Enter Directory: ";
    my $directoryPath = <>;
    chomp($directoryPath);
    chdir("$directoryPath") or die "Cant chdir to $directoryPath$!";
    
    opendir(DIR, $directoryPath) or die "Cant open $directoryPath$!";
    my @files = readdir(DIR); #Array of file names
    closedir (DIR) or die "Cant close $directoryPath$!";
    
    my $fileName = "File ";
    
    for my $i (0 .. @files)
    {
        rename($files[$i], $fileName . ($i+1)) or die "Cant rename file $files[$i]$!";
    }
    
    chdir; #return to home directory
    

    我可以正确输入路径,但然后错误信息(完全复制)是:

    Can't rename file .Permission denied at C:\path\to\file\RenameFiles.pl line 19, <> line 1.
    

2 个答案:

答案 0 :(得分:1)

错误

Can't rename file .Permission denied at C:\path\to\file\RenameFiles.pl line 19, <> line 1.

表示您正在尝试重命名文件.,这是一个特殊文件,是“当前目录”的快捷方式。您应该为代码添加例外以不重命名此文件,并添加名为..的例外。类似的东西:

next if $files[$i] =~ /^\./;

会这样做。这将跳过以句点.开头的任何文件。或者,您可以跳过目录:

next if -d $files[$i];   # skip directories (includes . and ..)

答案 1 :(得分:0)

正如TLP已经指出的那样,readdir返回...,它们对应于当前和父目录。

您需要对其进行过滤,以避免重命名目录。

use strict;
use warnings;
use autodie;

print "Enter Directory: ";
chomp( my $dirpath = <> );

opendir my $dh, $dirpath or die "Can't open $dirpath: $!";

my $number = 0;

while ( my $file = readdir($dh) ) {
    next if $file =~ /^\.+$/;
    my $newfile = "$dirpath/File " . ++$number;
    rename "$dirpath/$file", $newfile or die "Cant rename file $file -> $newfile: $!";
}

closedir $dh;

使用Path :: Class

的跨平台兼容性

简化此脚本和逻辑的一种方法是使用Path::Class来处理文件和目录操作。

use strict;
use warnings;
use autodie;

use Path::Class;

print "Enter Directory: ";
chomp( my $dirname = <> );

my $dir = dir($dirname);

my $number = 0;

for my $file ( $dir->children ) {
    next if $file->is_dir();
    my $newfile = $dir->file( "File" . ++$number );
    $file->move_to($newfile);
}