【问题标题】:simple way to test if a given filename is underneath a directory?测试给定文件名是否在目录下的简单方法?
【发布时间】:2014-05-10 22:04:31
【问题描述】:

是否有一个 Perl 模块(最好是核心模块)有一个函数可以告诉我给定的文件名是否在目录(或目录的子目录,递归)内?

例如:

my $f = "/foo/bar/baz";

# prints 1
print is_inside_of($f, "/foo");

# prints 0
print is_inside_of($f, "/foo/asdf");

我可以自己编写,但有一些复杂的因素,例如符号链接、相对路径、是否可以检查文件系统等。我宁愿不重新发明轮子。

【问题讨论】:

  • 这里有两种不同的技术:如果您想考虑符号链接,那么您必须对目录结构进行递归搜索以查看文件是否存在。如果您乐于忽略符号链接,则可以仅根据路径字符串做出决定

标签: perl filenames filepath subdirectory


【解决方案1】:

Path::Tiny 不在核心中,但它没有非核心依赖项,因此安装非常快捷。

use Path::Tiny qw(path);

path("/usr/bin")->subsumes("/usr/bin/perl");   # true

现在,它完全通过查看文件路径(在规范化它们之后)来完成此操作,因此根据您在符号链接等边缘情况下期望的行为类型,它可能合适也可能不合适。但对于大多数用途来说,这应该足够了。 (如果要考虑硬链接,唯一的方法是搜索整个目录结构并比较 inode 编号。)

【讨论】:

    【解决方案2】:

    如果你希望函数只对文件名(没有路径)和路径起作用,你可以使用File::Find

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    use File::Find;
    
    sub is_inside_of {
        my ($file, $path) = @_;
        my $found;
        find( sub { $found = 1 if $_ eq $file }, $path);
        return $found
    }
    

    如果您不想检查文件系统,而只想处理路径,请参阅File::Spec 了解一些可以帮助您的功能。但是,如果您想处理符号链接,就无法避免接触文件系统。

    【讨论】:

    • 感谢您的回答。不幸的是,如果给定目录下有很多文件,这种方法非常昂贵。
    猜你喜欢
    • 2014-04-01
    • 2011-07-16
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2011-04-17
    • 2016-03-08
    相关资源
    最近更新 更多