2011-01-20 16 views
32

Verilen yolun java kullanan başka bir yolun çocuğu olup olmadığını bulmaya çalışıyorum. Her iki yol da mevcut olmayabilir.Belirli bir yolun başka bir yolun çocuğu olup olmadığını nasıl kontrol edebilirim?

Say c:\Program Files\My Company\test\My Appc:\Program Files olası bir çocuktur. Ben getAbsolutePath() yerine getCanonicalPath() kullanacağı rağmen

Şu anda, olduğu gibi muhtemelen iyi çalışır Yani

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

mu bu örnek tüm dosya sistemi IO gerektirir? – user2586917

+0

[Java: Yolun bir dosyanın ebeveyni olup olmadığını kontrol edin] (http://stackoverflow.com/questions/28698125/java-check-if-path-is-parent-of-a-file) – Suma

+0

@Suma : Bağlandığınız soru bunun _duplicate_. – Jayan

cevap

41

Ayrıca çok daha kolay yapacak java.nio.file.Path kullanabilirsiniz. java.nio.file.Path.startsWith yöntemi tüm olası durumları ele alır gibi görünüyor.

Örnek:

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, ""); 
} 

çıkışları

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

bunun yerine "toAbsolutePath" nin "toRealPath" kullanabilirsiniz daha güvenilirlik gerekiyorsa

.

+1

Harika çözüm. Sadece Java 7 veya daha yeni sürümlerde mümkündür. –

+1

Bu, yollarda '..' ile nasıl çalışır? – Max

+0

"toAbsolutePath" yöntemi, yolun içindeki ".." ı çözer, böylece çalışması gerekir. Yine de test et. –

4

ile yapıyorum. Bu, aksi halde eşleştirmeyi bozan x/../y/z gibi garip yolları normalleştirmelidir.

+1

Hızlı ve düzeltilmiş çözüm için çok teşekkürler! – Jayan

+9

Hayır, hayır, bu ** doğru değil! Sorgulayan kişinin “myCheck()” yöntemi, kanonik hale getirildiğinde bile, “C: \ Prog” 'un C: \ Program Files'ın bir çocuğu olduğunu söyler. Aşağıya bakınız @biziclop. –

7

Örneğiniz için çalışacaktır. Çocuğun göreli yol olup olmadığı da true dönecektir (genellikle arzu edilir ki.)

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

[Özellikler] (http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URI.html#relativize (java.net.URI)) diyor, _ bir çocuk değil] o zaman verilen URI döndürülür. "_" Daha fazla anlam "parentURI.relativize (childURI)! = childURI" için kontrolünüzü değiştirmek daha iyidir. Aksi takdirde, fonksiyonunuz 'belkiChild' mutlak bir yol ise yanlış bir pozitif verir. – SnakE

+0

haklısın. Muhtemelen 'BelkiÇocuk' _relative_ 'ancak' olasıParent 'bir çocuk olmasaydı, yönteminizin hala' true 'olacağını söylerdim. Ama bu aslında bir problem değil, çünkü File.toURI() 'mutlak bir URI döndürmeyi garanti eder, böylece 'childURI' her zaman mutlaktır. Yine de, teklif ettiğim çek de iyi çalışmalı. – SnakE

+0

Eğer 'BelkiÇocuk' göreli ise o zaman potansiyel olarak çocuğun herhangi bir çocuğu olabilir - söyleyemezsiniz. – finnw

10

Asides gerçeğinden yolları olmayabilir (ve canonicalisation başarılı olmayabilir), bu makul bir benziyor Basit durumda çalışması gereken yaklaşım.

Bunu her adımda ebeveyn eşleşirse test, bir döngü içinde "belki çocuk" konulu getParentFile() arayarak bakmak isteyebilirsiniz

. Ebeveyn bir (gerçek) dizin değilse, karşılaştırmayı kısa devre yapabilirsiniz.

Belki şu gibi bir şey: isterseniz çocuk ilişkisi olduğu bu

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; 
} 

Not sıkı (yani bir dizin kendi başına bir çocuk değildir) Çizginin başlangıç ​​child atama değiştirebilir 9 child.getParentFile() olmak için, çocuğun bulunduğu dizinde ilk kontrol gerçekleşir.

+2

+ 1 OP bunu belirtmemiş olmasına rağmen, sorunun gerçek, varolan dosyalar ve yollar ile ilgisi yoktur. – biziclop

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

maybeChild.getCanonicalPath() startswith (possibleParent.getCanonicalPath().);

1

göreli yollar farkında olun!

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) 
0

Eski soruyu ancak önceden 1: scala olarak

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) 
    } 
} 

Eğer benzer bir yaklaşım olabilir: Ben basit çözüm böyle bir şey olduğunu düşünüyorum.7 çözeltisi: Bütünlüğü için

public boolean startsWith(String possibleRoot, String possibleChildOrSame) { 
     String[] possiblePath = new File(possibleRoot).getAbsolutePath().replace('\\', '/').split("/"); 
     String[] possibleChildOrSamePath = new File(possibleChildOrSame).getAbsolutePath().replace('\\', '/').split("/"); 

     if (possibleChildOrSamePath.length < possiblePath.length) { 
      return false; 
     } 

     // not ignoring case 
     for (int i = 0; i < possiblePath.length; i++) { 
      if (!possiblePath[i].equals(possibleChildOrSamePath[i])) { 
       return false; 
      } 
     } 
     return true; 
} 

java 1.7+ çözüm:

public boolean startsWith(String possibleRoot, String possibleChildOrSame) { 
     Path p1 = Paths.get(possibleChildOrSame).toAbsolutePath(); 
     Path p2 = Paths.get(possibleRoot).toAbsolutePath(); 
     return p1.startsWith(p2); 
} 
İlgili konular