Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if file is in (sub)directory

Tags:

java

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

I have two File objects.

File dir;
File file;

Both are guaranteed to exist. Let's assume

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

I want this check to return true

For now i am doing the check this way:

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

This seems to work with my limited tests, but i am unsure whether this might make problems on some operating systems. I also do not like that getCanonicalPath() can throw an IOException which i have to handle.

Is there a better way? Possibly in some library?

Thanks

like image 923
Johannes Dorn Avatar asked Aug 14 '13 09:08

Johannes Dorn


People also ask

How do I list files in a sub folder?

By default, ls lists just one directory. If you name one or more directories on the command line, ls will list each one. The -R (uppercase R) option lists all subdirectories, recursively.

How do I find a subdirectory file in Linux?

Finding Files Recursively in Linux You only need to define the main directory and the file name using the –name option. This command will search the file within the main directory and all subdirectories.

How do you see if a file is in a directory bash?

In order to check if a file exists in Bash using shorter forms, specify the “-f” option in brackets and append the command that you want to run if it succeeds. [[ -f <file> ]] && echo "This file exists!" [ -f <file> ] && echo "This file exists!" [[ -f /etc/passwd ]] && echo "This file exists!"


2 Answers

In addition to the asnwer from rocketboy, use getCanonicalPath() instad of getAbsolutePath() so \dir\dir2\..\file is 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);

Do not forget to catch any Exception with try {...} catch {...}.

NOTE: You can use FileSystem.getSeparator() instead of File.separator. The 'correct' way of doing this will be to get the getCanonicalPath() of the directory that you are going to check against as a String, then check if ends with a File.separator and if not then add File.separator to the end of that String, to avoid double slashes. This way you skip future odd behaviours if Java decides to return directories with a slash in the end or if your directory string comes from somewhere else than Java.io.File.

NOTE2: Thanx to @david for pointing the File.separator problem.

like image 68
Jorge Fuentes González Avatar answered Sep 28 '22 08:09

Jorge Fuentes González


I would create a small utility 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());
}
like image 26
dacwe Avatar answered Sep 28 '22 10:09

dacwe