Wie kann überprüft werden, ob ein bestimmter Pfad möglicherweise ein Kind eines anderen Pfads ist?

Lesezeit: 5 Minuten

Benutzeravatar von Jayan
Jayan

Ich versuche herauszufinden, ob der angegebene Pfad ein mögliches Kind eines anderen Pfads mit Java ist. Beide Pfade sind möglicherweise nicht vorhanden.

Sagen c:\Program Files\My Company\test\My App ist ein mögliches Kind von c:\Program Files.

Aktuell mache ich das mit

boolean myCheck(File maybeChild, File possibleParent)
{
    return maybeChild.getAbsolutePath().startsWith( possibleParent.getAbsolutePath());
}

  • Benötigt dieses Beispiel überhaupt Dateisystem-IO?

    – Benutzer2586917

    10. März 2014 um 16:09 Uhr

  • Mögliches Duplikat von Java: Überprüfen Sie, ob der Pfad einer Datei übergeordnet ist

    – Suma

    9. Februar 2017 um 21:34 Uhr

  • @Suma: Frage, die Sie verlinkt haben, ist Duplikat von diesem.

    – Jayan

    10. Februar 2017 um 11:39 Uhr

Benutzeravatar von Jecho Jekov
Jecho Jekov

Sie können auch verwenden java.nio.file.Path um dies viel einfacher zu tun. Der java.nio.file.Path.startsWith Methode scheint alle möglichen Fälle zu behandeln.

Beispiel:

private static void isChild(Path child, String parentText) {
    Path parent = Paths.get(parentText).toAbsolutePath();
    System.out.println(parentText + " = " + child.startsWith(parent));
}

public static void main(String[] args) {
    Path child = Paths.get("/FolderA/FolderB/File").toAbsolutePath();
    isChild(child, "/FolderA/FolderB/File");
    isChild(child, "/FolderA/FolderB/F");
    isChild(child, "/FolderA/FolderB");
    isChild(child, "/FolderA/Folder");
    isChild(child, "/FolderA");
    isChild(child, "/Folder");
    isChild(child, "/");
    isChild(child, "");
}

Ausgang:

/FolderA/FolderB/File = true
/FolderA/FolderB/F = false
/FolderA/FolderB = true
/FolderA/Folder = false
/FolderA = true
/Folder = false
/ = true
 = false

Wenn Sie mehr Zuverlässigkeit benötigen, können Sie verwenden toRealPath anstatt toAbsolutePath.

  • Tolle Lösung. Nur möglich in Java 7 oder neuer.

    – Tim Bender

    4. Juni 2013 um 17:56 Uhr

  • Wie geht das mit Pfaden um? .. in ihnen?

    – max

    25. November 2015 um 9:07 Uhr

  • Die Methode “toAbsolutePath” löst “..” innerhalb des Pfades auf, also sollte es funktionieren. Teste es aber besser.

    – Jecho Jekov

    25. November 2015 um 12:47 Uhr

  • Ich musste tatsächlich verwenden Paths.get(parentText).normalize() um richtig damit umgehen zu können ... toAbsolutePath() löste sie nicht, und toRealPath() löst eine IOException aus, wenn die Datei nicht existiert. Dies funktionierte unter OSX und Centos 6.7 mit Java 7.

    – Matt D

    15. März 2017 um 15:59 Uhr

  • Dies scheint nur mit Verzeichnissen unter root zu prüfen, was ist mit Ordner B, sollte das nicht auch ein Elternteil sein?

    – Calvin Taylor

    15. September 2020 um 16:14 Uhr

Benutzeravatar von biziclop
biziclop

File parent = maybeChild.getParentFile();
while ( parent != null ) {
  if ( parent.equals( possibleParent ) )
    return true;
  parent = parent.getParentFile();
}
return false;

  • Dies scheint die beste Lösung zu sein. Sind da irgendwelche Löcher drin?

    – Grummelsaurus

    20. März 2019 um 3:52 Uhr


  • @JoshuaD Kein Loch an sich, aber es wird beim Testen falsch zurückgegeben possibleParent selbst. Dies kann je nach Anwendungsfall erwünscht sein oder nicht. (Wenn Sie beispielsweise Pfade testen, um festzustellen, ob sie in einem zulässigen Verzeichnisbaum enthalten sind, würde dies im Stamm dieses Baums fehlschlagen.)

    – Ti Strga

    25. Februar 2021 um 16:45 Uhr

Benutzeravatar von Andrzej Doyle
Andrzej Doyle

Abgesehen davon, dass die Pfade möglicherweise nicht existieren (und die Kanonisierung möglicherweise nicht gelingt), sieht dies nach einem vernünftigen Ansatz aus, der im einfachen Fall funktionieren sollte.

Vielleicht möchten Sie sich das Aufrufen ansehen getParentFile() auf dem “vielleicht Kind” in einer Schleife und testet bei jedem Schritt, ob es mit dem Elternteil übereinstimmt. Sie können den Vergleich auch kurzschließen, wenn das übergeordnete Verzeichnis kein (echtes) Verzeichnis ist.

Vielleicht etwas wie das Folgende:

boolean myCheck(File maybeChild, File possibleParent) throws IOException
{
    final File parent = possibleParent.getCanonicalFile();
    if (!parent.exists() || !parent.isDirectory()) {
        // this cannot possibly be the parent
        return false;
    }

    File child = maybeChild.getCanonicalFile();
    while (child != null) {
        if (child.equals(parent)) {
            return true;
        }
        child = child.getParentFile();
    }
    // No match found, and we've hit the root directory
    return false;
}

Beachten Sie, dass, wenn Sie möchten, dass die untergeordnete Beziehung ist strikt (dh ein Verzeichnis ist kein Kind von sich selbst) können Sie den Anfangsbuchstaben ändern child Zuweisung auf Zeile 9 zu sein child.getParentFile() Die erste Prüfung findet also im enthaltenden Verzeichnis des untergeordneten Elements statt.

  • +1 Obwohl OP es nicht angegeben hat, ist es wahrscheinlich, dass sich die Frage auf tatsächliche, vorhandene Dateien und nicht auf Pfade bezieht.

    – Bizilop

    20. Januar 2011 um 11:54 Uhr

Benutzeravatar von finnw
finnw

Dies wird für Ihr Beispiel funktionieren. Es wird auch zurückkehren true wenn das Kind ein relativer Pfad ist (was oft wünschenswert ist.)

boolean myCheck(File maybeChild, File possibleParent)
{
    URI parentURI = possibleParent.toURI();
    URI childURI = maybeChild.toURI();
    return !parentURI.relativize(childURI).isAbsolute();
}

Das wird wahrscheinlich so funktionieren, wie es ist, obwohl ich es verwenden würde getCanonicalPath() statt getAbsolutePath(). Dies sollte alle seltsamen Pfade wie normalisieren x/../y/z die sonst das Matching vermasseln würden.

  • Nein, nein, das ist nicht richtig! Die des Fragestellers myCheck() Methode, selbst wenn sie kanonisiert ist, wird dies fälschlicherweise sagen C:\Prog ist ein Kind von C:\Program Files. Siehe Antwort unten von @biziclop.

    – Matt Quigley

    14. August 2012 um 19:00 Uhr

Benutzeravatar von Hosam Aly
Hosam Ali

maybeChild.getCanonicalPath().startsWith( possibleParent.getCanonicalPath() );

  • Nein, nein, das ist nicht richtig! Die des Fragestellers myCheck() Methode, selbst wenn sie kanonisiert ist, wird dies fälschlicherweise sagen C:\Prog ist ein Kind von C:\Program Files. Siehe Antwort unten von @biziclop.

    – Matt Quigley

    14. August 2012 um 19:00 Uhr

Benutzeravatar von Ľubomír Varga
Ľubomír Varga

Achten Sie auf relative Pfade! Ich denke, die einfachste Lösung ist ungefähr so:

public boolean myCheck(File maybeChild, File possibleParent) {
  if (requestedFile.isAbsolute) {
    return possibleParent.resolve(maybeChild).normalize().toAbsolutePath.startsWith(possibleParent.normalize().toAbsolutePath)
  } else {
    return maybeChild.normalize().toAbsolutePath.startsWith(possibleParent.normalize().toAbsolutePath)
  }
}

In Scala können Sie einen ähnlichen Ansatz haben:

val baseDir = Paths.get("/home/luvar/tmp")
val baseDirF = baseDir.toFile
//val requestedFile = Paths.get("file1")
val requestedFile = Paths.get("../.viminfo")
val fileToBeRead = if (requestedFile.isAbsolute) {
  requestedFile
} else {
  baseDir.resolve(requestedFile)
}
fileToBeRead.toAbsolutePath
baseDir.toAbsolutePath
fileToBeRead.normalize()
baseDir.normalize()
val isSubpath = fileToBeRead.normalize().toAbsolutePath.startsWith(baseDir.normalize().toAbsolutePath)

1449750cookie-checkWie kann überprüft werden, ob ein bestimmter Pfad möglicherweise ein Kind eines anderen Pfads ist?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy