【问题标题】:Perl: Bad Symbol for dirhandlePerl:dirhandle 的错误符号
【发布时间】:2014-09-14 12:17:45
【问题描述】:

这是我的代码:

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. 我尝试了另一种重命名文件的方法(如下),通过在目录句柄中以不同的方式重命名文件来尝试解决问题的不同方法,但这只会重复权限错误。

    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$!";
    

通过快速研究,我认为权限错误是 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.

【问题讨论】:

  • 无法使用给定的代码重现您的错误。此外,您的代码中仍然有i,它应该是$i
  • chdir-ed 到正确的目录了吗?举例说明你从 rename 得到的错误信息。
  • 您已添加代码以避免重命名 ... 对吗?否则,那是您的权限问题。
  • @TLP 已添加代码和确切的错误消息
  • @TLP 也修复了错误符号错误,语法稍有错误

标签: windows perl rename dir


【解决方案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 ..)

【讨论】:

  • 谢谢,下一个 if 行会去哪里,在 rename 行之前的 for 循环内?
  • 是的。你只能在循环中使用next(和last),并且在rename之后没有用。
  • @ikegami 是的。我会删除那部分。
【解决方案2】:

正如 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);
}

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 2017-07-30
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多