Tom Tresansky
Tom Tresansky

Reputation: 19877

Converting Relative Paths to Absolute Paths

I have an absolute path to file A.

I have a relative path to file B from file A's directory. This path may and will use ".." to go up the directory structure in arbitrarily complex ways.

Example A:

Example Bs:

How do I combine the two in order to get the simplest possible absolute path to file B?

Upvotes: 49

Views: 69979

Answers (9)

yegor256
yegor256

Reputation: 105193

Try FilenameUtils.normalize() from Apache commons-io

Upvotes: 3

rssdev10
rssdev10

Reputation: 301

String absolutePath = FileSystems.getDefault().getPath(mayBeRelativePath).normalize().toAbsolutePath().toString();

Upvotes: 30

U.Swap
U.Swap

Reputation: 1949

From your question, if i could get it right, you are looking to get abolute path from relative path, then you can do following.

File b = new File("../some/relative/path");
String absolute = b.getCanonicalPath(); // may throw IOException

or shorthand notation can be,

String absolute = new File("../some/relative/path").getCanonicalPath();

Upvotes: 5

Kyra
Kyra

Reputation: 5417

I know it isn't the best solution but can't you just combine the substring of fileA's path from 0 to the lastIndexOf("\") with fileB's path.

Example A:

  • C:\projects\project1\module7\submodule5\fileA

Example Bs:

  • ..\..\module3\submodule9\subsubmodule32\fileB

C:\projects\project1\module7\submodule5\..\..\module3\submodule9\subsubmodule32\fileB

If you don't want the .. in there then, it would take longer, but I recommend going through the path for fileB and keep taking the substring from 0 to the first index of \. Then check the substring. If it is .. then remove the substring from there and remove the substring from fileA's path from lastIndexOf(\) to length. Then repeat. That way you are removing the folders you don't need and the ..s.

So :

Example A:

  • C:\projects\project1\module7\submodule5\fileA

Example Bs:

  • ..\..\module3\submodule9\subsubmodule32\fileB

    --> C:\projects\project1\module3\submodule9\subsubmodule32\fileB

Upvotes: 0

Ravi
Ravi

Reputation: 1

Windows path to full Java path.

String winPath = downloadPath+"\\"+dir_contents[i].getName();
String absPath = winPath.replace("\\","\\\\");

Upvotes: -3

Marcus Junius Brutus
Marcus Junius Brutus

Reputation: 27296

What's better than just creating a utility that converts relative paths to absolute paths is to create a utility that converts any path passed to it into an absolute path so that you don't have to check on the client-side.

The below code works for me in both cases and I've used the String type at the signature of the method (both parameter and return value):

public static String toAbsolutePath(String maybeRelative) {
    Path path = Paths.get(maybeRelative);
    Path effectivePath = path;
    if (!path.isAbsolute()) {
        Path base = Paths.get("");
        effectivePath = base.resolve(path).toAbsolutePath();
    }
    return effectivePath.normalize().toString();
}

Changing the above code to expose Path types on the signature of the method is trivial (and actually easier) but I think that using String on the signature gives more flexibility.

Upvotes: 1

onlyhuman
onlyhuman

Reputation: 391

In Java 7 you can also use the Path interface:

Path basePath = FileSystems.getDefault().getPath("C:\\projects\\project1\\module7\\submodule5\\fileA");
Path resolvedPath = basePath.getParent().resolve("..\\..\\module3\\submodule9\\subsubmodule32\\fileB"); // use getParent() if basePath is a file (not a directory) 
Path abolutePath = resolvedPath.normalize();

Upvotes: 16

iviorel
iviorel

Reputation: 312

Here is the sample code that works for me.

 public String absolutePath(String relative, String absoluteTo)
    {       
        String[] absoluteDirectories = relative.split("\\\\");
        String[] relativeDirectories = absoluteTo.split("\\\\");
        int relativeLength = relativeDirectories.length;
        int absoluteLength = absoluteDirectories.length; 
        int lastCommonRoot = 0;
        int index;
        for (index = 0; index < relativeLength; index++)
            if (relativeDirectories[index].equals("..\\\\"))
                lastCommonRoot = index;
            else
                break;
        StringBuilder absolutePath = new StringBuilder();
        for (index = 0; index < absoluteLength - lastCommonRoot; index++)
        {  
             if (absoluteDirectories[index].length() > 0) 
                 absolutePath.append(absoluteDirectories[index] + "\\\\");                          
        }
        for (index = lastCommonRoot; index < relativeLength  - lastCommonRoot; 
                                                               index++)
        {  
             if (relativeDirectories[index].length() > 0) 
                 absolutePath.append(relativeDirectories[index] + "\\\\");                          
        }
        return absolutePath.toString();              
    }

Also I the conversion to relative:

public String relativePath(String absolute, String relativeTo) throws Exception
    {       
        String[] absoluteDirectories = absolute.split("\\\\");
        String[] relativeDirectories = relativeTo.split("\\\\");
        int length = absoluteDirectories.length < relativeDirectories.length ?
                        absoluteDirectories.length : relativeDirectories.length;
        int lastCommonRoot = -1;
        int index;
        for (index = 0; index < length; index++)
            if (absoluteDirectories[index].equals(relativeDirectories[index]))
                lastCommonRoot = index;
            else
                break;
        if (lastCommonRoot > -1){
            StringBuilder relativePath = new StringBuilder();
            for (index = lastCommonRoot + 1; index <absoluteDirectories.length;
                                                                         index++)
                if (absoluteDirectories[index].length() > 0)
                    relativePath.append("..\\\\");
            for (index = lastCommonRoot + 1; index <relativeDirectories.length-1;
                                                                         index++)
                relativePath.append(relativeDirectories[index] + "\\\\");
            relativePath.append(relativeDirectories[relativeDirectories.length - 1]);
            return relativePath.toString();         
        }
        else{
            throw new Exception("No common root found between working direcotry and filename");
        }            
    }

Upvotes: 0

Fabian Steeg
Fabian Steeg

Reputation: 45754

If I get your problem right, you could do something like this:

File a = new File("/some/abs/path");
File parentFolder = new File(a.getParent());
File b = new File(parentFolder, "../some/relative/path");
String absolute = b.getCanonicalPath(); // may throw IOException

Upvotes: 53

Related Questions