2013-08-14 11 views
7

Ich möchte prüfen, ob sich eine vorhandene Datei in einem bestimmten Verzeichnis oder einem Unterverzeichnis davon befindet.Überprüfen Sie, ob sich die Datei im (Unter) Verzeichnis befindet

Ich habe zwei Dateiobjekte.

File dir; 
File file; 

Beide sind garantiert zu existieren. Lassen Sie sich

dir = /tmp/dir 
file = /tmp/dir/subdir1/subdir2/file.txt 

annehmen mag ich diese Prüfung

Vorerst true zurück ich den Scheck auf diese Weise tue:

String canonicalDir = dir.getCanonicalPath() + File.separator; 
boolean subdir = file.getCanonicalPath().startsWith(canonicalDir); 

Dies scheint mit meinen begrenzten Tests zu arbeiten, aber ich bin nicht sicher, ob dies auf einigen Betriebssystemen Probleme verursachen könnte. Ich mag auch nicht, dass getCanonicalPath() eine IOException auslösen kann, die ich behandeln muss.

Gibt es einen besseren Weg? Möglicherweise in einer Bibliothek?

Danke

Antwort

-1

Wie wäre es, die Pfade zu vergleichen?

boolean areRelated = file.getAbsolutePath().contains(dir.getAbsolutePath()); 
    System.out.println(areRelated); 

oder

boolean areRelated = child.getAbsolutePath().startsWith(parent.getAbsolutePath()) 
+2

Dies könnte problematisch für Pfade sein, die Zeug wie "/tmp/something/../dir" enthalten, was in meiner Anwendung möglich ist. –

+0

Sie können einfach 'child.getAbsolutePath(). StartsWith (parent.getAbsolutePath())' verwenden, wenn dies der Fall ist. – rocketboy

+0

Eigentlich berechnet getAbsolutePath() alle solche '/../' Tokens und gibt den absoluten Pfad im Dateisystem zurück. –

0

Wenn Sie Arbeiten mit Datei planen und Dateinamen heavly Apache fileutils zu überprüfen und filenameutils Bibliotheken. Ist voll von nützlichen (und portalen wenn Portabilität mamdatory ist) funktioniert

0
public class Test { 
public static void main(String[] args) { 
    File root = new File("c:\\test"); 
    String fileName = "a.txt"; 
    try { 
     boolean recursive = true; 

     Collection files = FileUtils.listFiles(root, null, recursive); 

     for (Iterator iterator = files.iterator(); iterator.hasNext();) { 
      File file = (File) iterator.next(); 
      if (file.getName().equals(fileName)) 
       System.out.println(file.getAbsolutePath()); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

10

Ich würde eine kleines Programm Methode erstellen:

public static boolean isInSubDirectory(File dir, File file) { 

    if (file == null) 
     return false; 

    if (file.equals(dir)) 
     return true; 

    return isInSubDirectory(dir, file.getParentFile()); 
} 
+2

Ich würde zuerst überprüfen, ob die Datei tatsächlich eine Datei ist. Und es könnte nicht [finden Sie die Eltern] (http://stackoverflow.com/questions/11296949/created-file-has-no-parent). Das hört sich nach einer guten Idee an, sollte aber Teil einer größeren Lösung sein. –

7

Neben dem asnwer von Rocketboy verwenden getCanonicalPath() instad von getAbsolutePath() so \dir\dir2\..\file-\dir\file umgewandelt wird:

boolean areRelated = file.getCanonicalPath().contains(dir.getCanonicalPath() + File.separator); 
    System.out.println(areRelated); 

oder

boolean areRelated = child.getCanonicalPath().startsWith(parent.getCanonicalPath() + File.separator); 

Vergessen Sie nicht zu fangen Exception mit try {...} catch {...}.

HINWEIS: Sie können FileSystem.getSeparator() anstelle von File.separator verwenden. Der 'richtige' Weg ist das getCanonicalPath() des zu überprüfenden Verzeichnisses als String zu bekommen, dann prüfen, ob es mit einem File.separator endet und wenn nicht, dann fügen Sie File.separator am Ende dieses String hinzu, um zu vermeiden doppelte Schrägstriche.Auf diese Weise können Sie zukünftige ungerade Verhalten überspringen, wenn Java beschließt, Verzeichnisse am Ende mit einem Schrägstrich zurückzugeben oder wenn Ihre Verzeichniszeichenfolge von woanders als Java.io.File stammt.

HINWEIS2: Danke an @david für das Zeigen des File.separator Problems.

+0

Was ist mit '/ a' und'/ab/test.txt'? – david

+0

@david Gibt genau dasselbe zurück. Wenn Sie anstelle von umgekehrten Schrägstrichen nach Schrägstrichen fragen, kenne ich das Verhalten nicht, aber ich empfehle, das Betriebssystem nativ zu verwenden. Java hat eine Funktion zum Zurückgeben des systemeigenen Verzeichnistrennzeichens, aber ich kann mich nicht daran erinnern. –

+0

Mein Punkt war nicht über die Richtung der Schrägstriche überhaupt; Ich habe ein Gegenbeispiel gegeben, das zu einer falschen Antwort führt, indem ich die Strategie in Ihrer Antwort verwende. – david

4

Diese Methode sieht ziemlich solide:

/** 
* Checks, whether the child directory is a subdirectory of the base 
* directory. 
* 
* @param base the base directory. 
* @param child the suspected child directory. 
* @return true, if the child is a subdirectory of the base directory. 
* @throws IOException if an IOError occured during the test. 
*/ 
public boolean isSubDirectory(File base, File child) 
    throws IOException { 
    base = base.getCanonicalFile(); 
    child = child.getCanonicalFile(); 

    File parentFile = child; 
    while (parentFile != null) { 
     if (base.equals(parentFile)) { 
      return true; 
     } 
     parentFile = parentFile.getParentFile(); 
    } 
    return false; 
} 

Source

Es ist ähnlich zu der Lösung von dacwe aber Rekursion nicht verwenden (obwohl das keinen großen Unterschied in diesem Fall machen sollte) .

Verwandte Themen