• Perl5中19个最重要的文件系统工具


    在写脚本处理文件系统时,经常需要加载很多模块。其中好多有用函数分散在各种不同的模块中。它们有些是Perl的内置函数,有些是在同Perl一起发行的标准模块中,另外一些是通过CPAN安装的。

    下面来看15个最常用的工具。

    当前路径

    我经常需要知道当前所在的文件夹是什么。Cwd 模块有一个同名但是小写的函数 cwd,它会返回当前工作目录。

    1. use strict;
    2. use warnings;
    3.  
    4. use Cwd qw(cwd);
    5.  
    6. print cwd, " ";

    临时文件夹

    我经常需要创建一批临时文件,并且确保它们在脚本结束的时候会被自动删除。要满足这个需求,最简单的方法是以 CLEANUP 选项使用 File::Temp 模块的 tempdir 函数来创建一个临时文件夹。

    1. use strict;
    2. use warnings;
    3. use autodie;
    4.  
    5. use File::Temp qw(tempdir);
    6.  
    7. my $dir = tempdir( CLEANUP => 1 );
    8.  
    9. print "$dir ";
    10.  
    11. open my $fh, '>', "$dir/some_file.txt";
    12. print $fh "text";
    13. close $fh;

    与操作系统无关的路径

    如果上面的代码要在 Linux 和 Windows 上都要运行,人们会习惯在 Windows 平台上用反斜线分割路径。否则,在VMS上不能执行。而这就是 File::Spec::Functions模块中catfile函数的用武之地。

    1. use strict;
    2. use warnings;
    3.  
    4. use File::Spec::Functions qw(catfile);
    5.  
    6. use File::Temp qw(tempdir);
    7.  
    8. my $dir = tempdir( CLEANUP => 1 );
    9.  
    10. print "$dir ";
    11. print catfile($dir, 'some_file.txt'), " ";

    执行这个代码后,能看到临时文件夹被打印出来,紧跟其后的是文件名字。

    切换目录

    通常情况下,先切换工作目录到临时文件夹再进行操作会更简单。但是也存在其他情况的写测试。此时我们可以使用内置函数chdir。

    1. use strict;
    2. use warnings;
    3. use autodie;
    4.  
    5. use File::Temp qw(tempdir);
    6. use Cwd;
    7.  
    8. my $dir = tempdir( CLEANUP => 1 );
    9. print cwd, " ";
    10. chdir $dir;
    11. print cwd, " ";
    12.  
    13. open my $fh, '>', 'temp.txt';
    14. print $fh, 'text';
    15. close $fh;

    以上看起来可以正常工作,但是当File::Temp尝试删除文件夹,而我们仍然“在里面”(之前切换工作目录到它)时就会有问题。

    例如,我会得到下面的错误信息:

    cannot remove path when cwd is /tmp/P3DZP_rmqg for /tmp/P3DZP_rmqg:
    

    为了避免这种情况,我通常会在切换目录之前保存cwd的返回值,并且在最后再次调用chdir。

    1. my $original = cwd;
    2.  
    3. ...
    4.  
    5. chdir $original;

    这样仍然会有个小问题。如果我在脚本中间调用exit(),或者在执行到chdir $original之前抛出异常而终止脚本,会发生什么?

    Perl提供了一个解决方案:把最后一个chdir包裹在END块中。如此,就会确保无论何时、以何种方式退出脚本,这些代码都会执行到。

    1. my $original = cwd;
    2.  
    3. ...
    4.  
    5. END {
    6. chdir $original;
    7. }

    相对路径

    当写一个多文件构成的项目(例如一个或多个脚本,多个模块,也可能是多个模板),并且我不想“安装”它们时,最好的目录组织方式是:确保每个文件都在一个固定的相对位置。

    所以,我的项目目录通常会包含一个脚本子文件夹,一个模块文件夹(lib), 一个模板文件夹, 等等:

    project/
         scripts/
         lib/
         templates/
    

    那么,如何才能确保脚本能够找到模板? 我有好几个处理办法:

    1. use strict;
    2. use warnings;
    3. use autodie;
    4.  
    5. use FindBin qw($Bin);
    6. use File::Basename qw(dirname);
    7. use File::Spec::Functions qw(catdir);
    8.  
    9. print $Bin, " "; # /home/foobar/Rocket-Launcher/scripts
    10. print dirname($Bin), " "; # /home/foobar/Rocket-Launcher
    11. print catdir(dirname($Bin), 'templates'), " "; # /home/foobar/Rocket-Launcher/templates

    FindBin模块导出的参量$bin存放着当前脚本的目录路径。 在我们的例子中就是指向project/scripts/文件夹的路径。

    File::Basename中的dirname函数会传入一个路径,并返回除最后一部分之外的路径。

    最后一行File::Spec::Functions模块的catdir函数基本上和我们之前看到的catfile一样。

    除了打印到屏幕上,当然也可以使用catdir的返回值来表示templates路径。

    从相对路径中加载模块

    大部分情况下,要查找和加载的模块都会在项目的lib/文件夹中。为此,我们会把之前的代码和lib指令连用。这样会改变@INC变量的值,把相对路径添加在数组开头。

    1. use strict;
    2. use warnings;
    3. use autodie;
    4.  
    5. use FindBin qw($Bin);
    6. use File::Basename qw(dirname);
    7. use File::Spec::Functions qw(catdir);
    8.  
    9. use lib catdir(dirname($Bin), 'lib');
    10.  
    11. use Rocket::Launcher;

    假定存在lib/Rocket/Launcher.pm文件。

  • 相关阅读:
    最小生成树
    负环详解
    P2053 [SCOI2007]修车
    P3254 圆桌问题
    P3114 [USACO15JAN]踩踏Stampede
    SP1043 GSS1
    SP2713 GSS4
    导出mysql内数据 python建倒排索引
    社团管理系统——总结报告
    北京地铁出行线路规划——代码实现
  • 原文地址:https://www.cnblogs.com/nkwy2012/p/6027157.html
Copyright © 2020-2023  润新知