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
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();
Try FilenameUtils.normalize() from Apache commons-io
String absolutePath = FileSystems.getDefault().getPath(mayBeRelativePath).normalize().toAbsolutePath().toString();
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");
}
}
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.
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();