Perl:打开文件

Perl:打开文件,perl,Perl,我正在尝试打开作为参数接收的文件 当我将参数存储到全局变量中时,open会成功工作 但是 如果我使用give,则在打开文件失败时进行设置 原因是什么 #use strict; use warnings; #my $FILE=$ARGV[0]; #open Fails to open the file $FILE $FILE=$ARGV[0]; #Works Fine with Global $FILE open(FILE) or die "\n ". "Cannot

我正在尝试打开作为参数接收的文件

当我将参数存储到全局变量中时,open会成功工作

但是

如果我使用give,则在打开文件失败时进行设置

原因是什么

#use strict;
use warnings;

#my $FILE=$ARGV[0];   #open Fails to open the file $FILE

$FILE=$ARGV[0];        #Works Fine with Global $FILE
open(FILE)
    or
die "\n ". "Cannot Open the file specified :ERROR: $!". "\n";
这一切都在:

如果省略EXPR,则为与相同名称的标量变量 文件句柄包含文件名。(注意 变量——那些用“my”声明的变量——对此不起作用 目的;因此,如果您使用“我的”,请在通话中指定EXPR )

请注意,这不是指定文件名的好方法。如您所见,它对所处的变量类型有一个硬约束,通常最好避免使用它所需的全局变量或它打开的全局文件句柄

使用词法文件句柄可以控制其作用域,并自动处理关闭:

open my $fh, '<', "filename" or die "string involving $!";

打开我的$fh,”一元打开仅对包(全局)变量有效。这在上有记录

打开文件进行读取的更好方法是:

my $filename = $ARGV[0];           # store the 1st argument into the variable
open my $fh, '<', $filename or die $!; # open the file using lexically scoped filehandle

print <$fh>; # print file contents
my$filename=$ARGV[0];#将第一个参数存储到变量中
打开我的$fh,“
使用strict;
使用警告;
我的$file\u name=shift@ARGV;
打开(我的$file,From

如果省略EXPR,则与FILEHANDLE同名的标量变量包含文件名。(请注意,词法变量(使用my声明的变量)不适用于此目的;因此,如果使用my,请在调用open时指定EXPR。)


这种perl风格已经过时了。您最好还是打开我的$file,“一元open被记录为只在包变量上工作。@William:那里不应该有编码吗?
open(FH,“<:encoding(UTF-8)”,$pathname)
@tchrist抓住了一个好机会,它有力地支持从ARGV读取数据。@William:在ARGV上设置编码有点棘手:它通常需要
PERL\u UNICODE
envariable或相应的
PERL-CSD
命令行标志,但这些只有在我们谈论UTF-8时才起作用。
使用openpragma可以处理交替编码。要将其与环境变量一起传递,需要一些秘密:
PERL5OPT='-Mopen=:std,in,:encoding(MacRoman),OUT,:utf8'
起作用。+1需要再说一遍:如果
strict
抱怨,这意味着您需要修复代码,而不是注释掉
strict
。我以前说过,我要再说一遍:这个答案没有抓住要点。简单的问题是为什么一元open只适用于包变量答案是,这是因为它是这样记录的。所有其他的都是在缺少的蛋糕上结霜。另外,您忘记了在
open(FH,“<:encoding(UTF-8)”,$path中指定编码
。如果你这么小心的话,你不应该也测试一下
@ARGV
的合理性吗?最后,你怎么知道他们不希望像
-
这样的文件名以标准的Unix方式指定std{in,out,which}?此外,这是一个非常糟糕的习惯用法。Perl已经能够通过ARGV自动打开作为参数列出的文件。在Perl中,几乎没有什么好的理由显式打开一个名为@ARGVIt的文件,而该文件不是习惯用法。向用户展示如何打开文件可能比告诉他更有用“一元打开被记录为仅对包变量起作用。”也许不是,但这毕竟是我们有多种答案的原因。@zoul我同意举个例子是好的,我的评论并不是对你的回答的批评,而是对粗心大意的读者的警告。许多perl代码似乎是由不知道perl免费做了很多这方面工作的人编写的。这个答案没有得到这就是问题所在。简单的问题是为什么一元open只适用于包变量。简单的答案是,这是因为它被记录在案。其他一切都是在一块缺失的蛋糕上结霜。@tchrist:好的,我在回答中添加了这一点。谢谢。我通常不会对尝试过的答案投反对票(这就是为什么我在这里没有这么做的原因)。我更喜欢指出他们错过了什么。谢谢你修复它。好的方面:使用magic ARGV通常比显式打开要好得多。但是如果(!@ARGV&&t STDIN){警告“$0:从STDIN读取…\n”}添加
if(!@ARGV&&t STDIN)
帮助那些系统中缺少适当的
^T
tty字符的人。但是,magic ARGV仅在
@ARGV
最初为空时使用stdin,而不是在它耗尽时使用;您的答案表明并非如此。@tchrist:yes和no…在
耗尽ARGV并返回一次undef之后(您刚才所说的),它将重新开始,如果你没有做任何改变,它将以一个空的@ARGV开始,因此回到STDIN(我刚才说的)。我承认大多数人不会自动通过第一个undef并进行编辑。我毫不怀疑你会这样做。:)我只是在为我最初写的东西辩护。
use strict;
use warnings;

my $file_name = shift @ARGV;
open(my $file, '<', $file_name) or die $!;
…
close($file);