加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

《Perl语言入门》之四――输入与输出

发布时间:2020-12-16 00:12:45 所属栏目:大数据 来源:网络整理
导读:标准输入输出 STDIN可以用于接收键盘输入或是文件输入。在标量上下文中执行该操作时,会返回输入中的下一行。 while STDIN { chomp; print "I saw $_";}foreach STDIN { chomp; print;} 看起来上例中的“while”循环和“foreach”的行为完全一样,其实是有些

标准输入输出

STDIN可以用于接收键盘输入或是文件输入。在标量上下文中执行该操作时,会返回输入中的下一行。

while <STDIN> {
    chomp;
    print "I saw $_";
}
foreach <STDIN> {
    chomp;
    print;
}

看起来上例中的“while”循环和“foreach”的行为完全一样,其实是有些差别的――在while循环里,Per会读取一行输入,把它存入某个变量并且执行循环的主体,接下来它会回去寻找其他输入行;foreach循环中,行输入操作符会在列表上下文中执行(因为foreach需要逐项处理列表内容),因此Perl会将全部内容读入内存,然后才开始执行循环。当需要处理的输入数据长度很大时,比如处理400M大小的Web服务器日志文件,foreach的效率会比while低很多。因此最好的做法是尽量使用while循环,让它每次处理一行。


钻石操作符的输入<>

钻石操作符提供类似 标准Unix工具程序的参数输入方式,例如对于如下Perl程序“my_program”:

while <> {
    chomp;
    print;
}

如果执行命令“./my_program fred barney betty”,它应该会处理文件fred,接着是barney,最后是betty。(钻石操作符怎么会知道检查命令行参数呢?其实它的参数是来自@ARGV数组)

如果执行命令是没有指定调用参数,程序会从标准输入流采集数据。

当然还有个例外,如果参数中包含连字符“-”,则Perl代码处理到连字符时,会临时改从标准输入读取数据。


使用print/printf/say输出到标准输出

Print操作符会读取后续列表中的所有元素,并把每一项一次送到标准输出。

print <>; #相当于Unix下的cat命令 
print sort <>; #相当于Unix下的sort命令

如果对print的输出格式不够满意,还可以使用printf来产生格式化过的输出结果。

printf "Hello,%s; your password expires in %d days!n",$user,$days_to_die;

当然Perl一如既往地提供了更方便的格式"%g" (你可以把"g"当成"General"数字转换)。

一般来说,我们编写printf的格式化字符串时已经确定了替换参数的个数和类型,不过万事没有绝对,下面的例子就是用程序在运行时动态产生格式字符串。

my @items = qw( wilma dino pebbles ); 
my $format = "The items are: n" . ("%10sn" x @items); 
printf $format,@items;

另外,有个叫Perl Power Tools (PPT)的项目目标就是用perl重写所有经典Unix工具程序,但是在重写shell的时候陷入了难题。PPT项目一度非常有用,因为它使所有便准的工具程序可以运行在非Unix机器上。

Say函数的功能和print的差不多,但在打印每行内容时都会自动加上换行符。所以下面几种写法的输出结果都一样:

use 5.010 
print "Hello!n"; 
print "Hello!" . "n"; 
say "Hello!";


文件句柄

一般使用全大写字母来命名文件句柄,但是有6个个数文件句柄是Perl保留的――STDIN、STDOUT、STDERR、DATA、ARGV以及ARGVOUT。

open CONFIG,'dino'; #打开一个文件 
open CONFIG,'<dino' #只读方式打开一个文件 
open REDROCK,'>fred' #创建一个新的文件,如果已经存在,则清除原有内容并以新内容代替 
open LOG,'>>logfile' #追加方式打开一个文件,如果文件不存在,则创建一个新文件

5.6版的Perl里,加入了open的三个参数的写法:

open CONFIG,'<','dono'; 
open BEDROCK,'>',$file_name; 
                                                                         
open CONFG,'<:encoding(UTF-8)',$file_name; #使用UTF-8编码打开文件,这种书写方式会确认编码是否正确 
open BEDROCK,'>:utf8',&logfile_name(); #这种简写的方式不会考虑输入输出的数据是否真的是合法的UTF-8字符串

我们可以通过下面的这条命令打印出说有perl能理解的字符编码清单:

% perl -MEncode -le "print for Encode->encodings(':all')"

除了字符编码之外,数据输入或输出过程中还可以做其他转换操作。比如DOS风格和Unix风格的换行符:

open BEDROCK,'>:crlf',$file_name; #按照DOS换行符风格写入文件 
open BEDROCK,'<:crlf',$file_name; #读取DOS风格的文件



关闭文件句柄

close BEDROCK;


出错处理

当Perl遇到致命错误时,你的程序应该立刻中止运行,并发出错误信息告知原因。这样的功能可以用die函数来实现。

if ( ! open LOG,'>>','logfile' ) { 
    die "Cannot create logfile: $!"; #die函数会终止程序的运行并打印出错信息 
}

"$!"代表可读的系统错误信息。一般来说,当系统拒绝我们的请求时,"$!"会给出一个解释,类似于C语言中调用perror取得的字符串。

如果Perl遇到的错误是非致命的,可以使用warn函数送出警告信息。warn函数的功能就是产生类似于Perl的内置警告信息的信息(比如启用警告信息时,使用某个undef变量却将它当成已有的值来参与计算,就会触发警告信息)。


自动检测致命错误

从Perl 5.10开始,为人称道的autodie编译指令已经成为标准库的一部分。

use autodie;

这条编译指令是靠判别具体操作的类型来工作的。如果Perl内置函数调用了操作系统接口的话,那么中途出现的错误并不是编程人员所能控制的,所以一旦发现系统调用出错,autodie便会自动帮你调用die。


使用文件句柄

以写入或添加方式打开文件后,可以直接使用print或printf将字符串输出到文件中:

print LOG "Captain's log,stardate 3.14159"; 
printf STDERR "%d percent complete.n",$done/$total * 100;

如果print/printf的参数列表没有提供文件句柄,则字符串默认被输出到STDOUT。不过可以使用select操作符改变默认的文件句柄,另外还有一个很奇特的变量"$|",当它的值被设为1,就会使当前的默认句柄在每次输出操作后立刻刷新缓冲区。所以,如果要让输出的内容立即显示(比如在读取监视某个耗时程序的实时日志时),应该这么做:

select LOG; # 将默认输出设定为LOG文件句柄 
$|= 1; # 不要将LOG的内容保留在缓冲区 
select STDOUT; 
print LOG "This gets written to the LOG at once!n";

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读