zoukankan      html  css  js  c++  java
  • Perl文件句柄引用

    目前还没介绍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 @_, "
    ";
    }
    

    字符串句柄

    除了可以将句柄关联到文件(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
    ";
    print {$string_fh} "second line";
    
    print $string,"
    ";   # 输出两行:first line和second line
    

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

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

    文件句柄容器

    说法有点高大上,其实就是将文件句柄存储到数据结构中(例如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";
    }
    
  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/9740059.html
Copyright © 2011-2022 走看看