Check if the file is in the (under) directory

I would like to check if an existing file is in a specific directory or subdirectory of this.

I have two File objects.

File dir; File file; 

Both are guaranteed. Let's pretend that

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

I want this check to return true

Now I do the check like this:

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

This is similar to my limited tests, but I'm not sure if this can cause problems on some operating systems. I also don't like the fact that getCanonicalPath () can throw an IOException that I have to handle.

Is there a better way? Perhaps in some library?

thanks

+8
java
source share
8 answers

I would create a small useful method:

 public static boolean isInSubDirectory(File dir, File file) { if (file == null) return false; if (file.equals(dir)) return true; return isInSubDirectory(dir, file.getParentFile()); } 
+10
source share

In addition to rocketboy's asnwer, use getCanonicalPath() instad getAbsolutePath() , so \dir\dir2\..\file converted to \dir\file :

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

or

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

Remember to catch Exception with try {...} catch {...} .

NOTE. You can use FileSystem.getSeparator() instead of File.separator . The β€œright” way to do this is to get getCanonicalPath() directory that you are going to check as String , and then check to see if it ends with File.separator , and if not, add File.separator to the end of this String to avoid double slashes. This way you skip future odd behavior if Java decides to return the slash directories at the end or if your directory line comes from somewhere else than Java.io.File .

NOTE2: Thanx to @david to indicate File.separator problem.

+10
source share

This method looks pretty solid:

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

A source

This is similar to dacwe's solution, but does not use recursion (although this should not make much difference in this case).

+5
source share

If you plan to work with files and file names, carefully check the apache fileutils and filenameutils libraries. Full of useful (and portale if portability is mamdatory) functions

0
source share
 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(); } } 

}

0
source share

You can navigate the file tree starting from your DIR. On Java 7, there is a Files.walkFileTree method. You must write your own visitor to check if the current node file is found. Another dock: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#walkFileTree%28java.nio.file.Path,%20java.util.Set,%20int ,% 20java.nio.file.FileVisitor% 29

0
source share

You can do this, however it will not handle all use cases, for example, dir = / somedir /../ tmp / dir / etc ..., unless this file has also been defined.

 import java.nio.file.Path; import java.nio.file.Paths; public class FileTest { public static void main(final String... args) { final Path dir = Paths.get("/tmp/dir").toAbsolutePath(); final Path file = Paths.get("/tmp/dir/subdir1/subdir2/file.txt").toAbsolutePath(); System.out.println("Dir: " + dir); System.out.println("File: " + file); final boolean valid = file.startsWith(dir); System.out.println("Valid: " + valid); } } 

In order for the checks to work correctly, you really need to display them using toRealPath() or, in your example, getCanonicalPath() , but then you must handle the exceptions for these examples, which is absolutely correct, that you must do this.

0
source share

How about comparing paths?

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

or

 boolean areRelated = child.getAbsolutePath().startsWith(parent.getAbsolutePath()) 
-one
source share

All Articles