如何确定目录是否位于文件系统层次结构中另一个目录之下或之上

时间:2015-03-05 19:33:01

标签: java algorithm file directory

我目前正在开发一个类似于FTP的项目。为此,我需要实现虚拟chrooting,它也适用于Windows平台。

我目前的方法是每个用户都有一个特定的主目录(由File对象表示),每次用户尝试访问文件或目录时,服务器都会检查此文件或目录是否为在这个主目录内或不。

可悲的是,我不确定,如何以不占用太多CPU时间和HDD访问时间的方式实现此检查。人们可以简单地尝试走上目录,如果我们落在一个等于给定主目录的目录上,我们会感到满意。如果我们到达根目录,我们返回false,因为给定文件很可能不在主目录中。

我确信这项检查会有效,但我也认为这样做会非常昂贵,而且在多用户环境中也可能非常低效。

我将非常感谢能够更好地设计此算法。也许甚至存在一种方法呢?虽然我还没找到。

提前致谢!

//编辑:根据要求,以下是此文件结构的一些示例

- /
    - home/
        - user1/
            - file1.txt
            - file2.txt
        - user2/
            - picture.png
    - someDir/

我们假设有2个用户(“user1”和“user2”),其中user1的主目录为“/ home / user1”,user2为“/ home / user2”。
如果在这种情况下应用,我正在寻找的方法应该给出以下结果:

isInsideHome("/home/user2/picture.png", "user1") -> false
isInsideHome("/home/user1/file1.txt", "user1") -> true
isInsideHome("/", "user1") -> false
isInsideHome("/home", "user2") -> false

我希望这些例子能够澄清我在寻找的东西。

1 个答案:

答案 0 :(得分:1)

假设您没有调用createNewFile(),exists()等方法,java.io.File不需要HDD访问,并且只会占用最少的CPU。

例如,我的计算机上不存在以下路径,但代码无一例外地执行。

public static void main(String[] args) {
    System.out.println(isInsideHome("/home/user2/picture.png", "user1"));
    System.out.println(isInsideHome("/home/user1/file1.txt", "user1"));
    System.out.println(isInsideHome("/", "user1"));
    System.out.println(isInsideHome("/home", "user2"));
}

private static boolean isInsideHome(String pathStr, String leaf) {
    File path = new File(pathStr);
    File search = new File(leaf);
    while ((path = path.getParentFile()) != null) {
        if (search.getName().equals(path.getName())) {
            return true;
        }
    }
    return false;
}

java.io.File.getParentFile()的来源显示不涉及硬盘访问...

public static void main(String[] args) {
    System.out.println(isInsideHome("/home/user2/picture.png", "user1"));
    System.out.println(isInsideHome("/home/user1/file1.txt", "user1"));
    System.out.println(isInsideHome("/", "user1"));
    System.out.println(isInsideHome("/home", "user2"));
}

private static boolean isInsideHome(String pathStr, String leafStr) {
    File path = new File(pathStr);
    File leaf = new File(leafStr);
    while ((path = path.getParentFile()) != null) {
        if (leaf.getName().equals(path.getName())) {
            return true;
        }
    }
    return false;
}