目前还没介绍Perl的面向对象,所以这节内容除了几个注意点,没什么可讲的。

以前经常使用大写字母的句柄方式(即所谓的裸字文件句柄,bareword filehandle),现在可以考虑转向使用变量文件句柄的形式,因为只有使用变量句柄的方式,才能创建文件句柄引用。

open DATA,">>","/tmp/a.log" or die "can't open file: $!";
open my $data_fh ,">>","/tmp/a.log" or die "can't open file: $!";
open my $fh, '<', 'castaways.log' or die "Could not open castaways.log: $!";

裸字文件句柄和变量文件句柄用法是完全一致的,能用裸字文件句柄的地方都可以替换为变量文件句柄:

while( <DATA> ) { ... }
while( <$log_fh> ) { ... }

不管使用裸字还是变量文件句柄的方式,在退出文件句柄所在作用域的时候,都会自动关闭文件句柄,无需手动close。

只是需要注意的是,使用变量文件句柄的方式,在say/print输出的时候,指定文件句柄时需要使用大括号包围,以免产生歧义:

print {$data_fh} "your output content";

如果想要让某个函数指定输出的文件句柄,也简单,只需将文件句柄作为一个参数即可:

log_message( $log_fh, 'My name is Mr. Ed' );
sub log_message {
my $fh = shift;
print $fh @_, "\n";
}

字符串句柄

除了可以将句柄关联到文件(open)、管道、套接字、目录(opendir),还可以将句柄关联到字符串。也就是将一个变量作为文件句柄的关联对象,从这个变量读或从这个变量写。

例如:

open my $string_fh, '>>', \my $string;
open my $string_fh, '<', \$multiline_string;

上面第一句声明了一个词法变量$string(初始化为Undef),同时创建了一个文件句柄$string_fh,这个文件句柄的输出对象是词法变量$string指向的数据对象。第二句则是从字符串$multiline_string中读取数据。

现在可以向这个文件句柄中输出一些数据,它们会存储到$string中:

#!/usr/bin/perl

open my $string_fh, ">>",\my $string or die "...$!";

print {$string_fh} "first line\n";
print {$string_fh} "second line"; print $string,"\n"; # 输出两行:first line和second line

如果想将流向标准输出STDOUT默认设备(终端屏幕)的内容改输出到字符串中,需要小心一些,因为STDOUT毕竟是标准输出,程序的很多部分可能都需要使用它。所以,尽量在一小片范围内修改标准输出的目标。例如,使用大括号包围,并将STDOUT进行local化(裸字文件句柄只能用local修饰):

print "1. This goes to the real standard output\n";
my $string;
{
local *STDOUT;
open STDOUT, '>', \ $string;
print "2. This goes to the string\n";
$some_obj->noisy_method(); # this STDOUT goes to $string too
}
print "3. This goes to the real standard output\n";

文件句柄容器

说法有点高大上,其实就是将文件句柄存储到数据结构中(例如hash、数组),做一个装文件句柄的容器。

例如,有一个文件a.txt,内容如下。现在想将每一行第二列、第三列存储到以第一列命名的变量中。

malongshuai big 1250
malongshuai small 910
gaoxiaofang big 1250
gaoxiaofang small 450
tuner middle 1218
wugui middle 199

如下:

use v5.10; # for state
while( <> ) {
state $fhs; # 定义一个hash引用变量
my( $source, $destination, $bytes ) = split;
unless( $fhs->{$source} ) { # 当hash键(第一列)不存在时,创建字符串句柄
open my $fh, '>>', $source or die '...';
$fhs->{$source} = $fh;
}
say { $fhs->{$source} } "$destination $bytes";
}

Perl文件句柄引用的更多相关文章

  1. perl文件句柄的传递

    perl 返回文件句柄的2种方式 1.使用 \* #!/usr/bin/perl use strict; sub openfile() { my $path=shift; open(FILE,&quo ...

  2. Perl文件句柄相关常量变量

    文件句柄相关变量 对应的官方手册:http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles 默认情况下: $/:输入行 ...

  3. Perl解除引用:从引用还原到数据对象

    使用引用可以指向数据对象,这似乎很简单. @name1=qw(longshuai wugui); @name2=qw(xiaofang tuner); $ref_name=\@name1; push ...

  4. Perl子程序引用和匿名子程序

    子程序也有引用,也有匿名子程序.假设你已经具备了数组.hash的引用知识,所以这里简单介绍一下. $ref_sub = \&mysub; # 子程序引用,&符号必须不能少 &{ ...

  5. Perl正则表达式引用

    正则表达式两篇: 基础正则 Perl正则 本文是对Perl正则的一点扩展,主要内容是使用qr//创建正则对象,以及一些其它的技巧. qr//创建正则对象 因为可以在正则模式中使用变量替换,所以我们可以 ...

  6. perl指针引用

    http://bbs.chinaunix.net/forum-viewthread-tid-570031.html

  7. Perl系列文章

    0.Perl书籍推荐 Perl书籍下载 密码:kkqx 下面是一些我学习Perl过程中读过完整的或部分章节的觉得好的书. 入门级别1:<Perl语言入门>即小骆驼 入门级别2:<In ...

  8. Perl的IO操作(2):更多文件句柄模式

    open函数除了> >> <这三种最基本的文件句柄模式,还支持更丰富的操作模式,例如管道.其实bash shell支持的重定向模式,perl都支持,即使是2>&1 ...

  9. Perl引用入门

    在perl中只有3种基本的数据结构:标量.数组.hash.变量可以是数值,可以是字符串. 这三种基本数据结构的数据存储方式如下: 但是,仅仅由这3种基本结构,就可以构造出更复杂的数据结构,例如hash ...

随机推荐

  1. CodeSampler DX9 Full-screen initialization

    D3D新手,请轻拍. 最近在学CodeSampler上的DX9范例.编译环境是VS2012.搭编译环境用了一两天,另行开文吐槽(有时间的话). 本文讲讲Full-screen initializati ...

  2. python按照指定字符或者长度 截取字符串

    1.截取指定位置字符串 Python字符串可以理解为一个数组,获取某一部分的可以使用 str[beginIndex:endPosition],其中str为需要截取的字符串,beginIndex为需要截 ...

  3. shell脚本颜色输出(实例未编辑)

    颜色输出通过echo 输出,需要加-e echo -e "\033[背景颜色;字体颜色\033[0m" 背景颜色 40 设置黑色背景 41 设置红色背景 42 设置绿色背景 43 ...

  4. Djangoの1

    有ip无路由是404,ip也无是无法访问此网站.url中?前的是路由,?后是GET请求的各组参数.   子项目和子应用下的两类urls.py:[]内的各个路由函数url,其首参网址的开头无/,结尾有/ ...

  5. Unity3D在移动平台下加载AssetBundle导致Shader效果不正确的问题

    这个问题,主要还是在移动平台下开发导致的. 在编辑器里调试加载AB时会导致Shader效果不正确的原因,主要还是编辑器下加载以IOS或是ANDROID平台打包的AB它所使用的shader已经编译成对应 ...

  6. sqoop错误集锦1

    1.当时初学Sqoop的时候,mysql导入到hdfs导入命令执行以后,在hdfs上面没有找到对应的数据,今天根据这个bug,顺便解决这个问题吧,之前写的http://www.cnblogs.com/ ...

  7. CCNA学前基础一

    网络设备: 集线器:集线器就是一种采用共享式工作状态的设备.Hub将信号放大后传输给其他端口,即传输线路是共享的. 交换机:用于连接终端设备,和基本的安全功能还有广播域的隔离.优点实现多用户同时访问, ...

  8. 初学mybatis和mysql碰到的问题

    今天学习了下使用mybatis操作数据库,期间也是各种问题出现,幸好现在网络发达,网络上很多都可以解决,现在总结一下: Exception in thread "main" org ...

  9. 学习Java的进度

    这周我们通过老师的讲解带着我们回到了第八周的知识点.lambda表达式也是一种简化程序的好方法,通过回调程序的测试可以对比出lambda 表达式少的不是一两行代码,可以少了类中方法的定义,直接使用.内 ...

  10. QEMU KVM libvirt 手册(3) - Storage Media

    访问Hard Drive 使用-hda –hdb qemu-system-x86_64 -enable-kvm -name ubuntutest  -m 2048 -hda ubuntutest.im ...