Преобразование относительных путей в абсолютные пути
У меня есть абсолютный путь к файлу A.
У меня есть относительный путь к файлу B из каталога файла A. Этот путь может и будет использовать ".." для перехода к структуре каталогов произвольно сложными способами.
Пример A:
-
C:\projects\project1\module7\submodule5\fileA
Пример Bs:
-
..\..\module3\submodule9\subsubmodule32\fileB
-
..\submodule5\fileB
-
..\..\module7\..\module4\submodule1\fileB
-
fileB
Как объединить эти два, чтобы получить самый простой возможный абсолютный путь к файлу B?
Ответы
Ответ 1
Если я правильно понимаю вашу проблему, вы можете сделать что-то вроде этого:
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
Ответ 2
В Java 7 вы также можете использовать интерфейс Path:
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();
Ответ 3
String absolutePath = FileSystems.getDefault().getPath(mayBeRelativePath).normalize().toAbsolutePath().toString();
Ответ 4
Попробуйте FilenameUtils.normalize()
от Apache commons-io
Ответ 5
От вашего вопроса, если бы я мог сделать это правильно, вы ищете, чтобы получить абсолютный путь от относительного пути, то вы можете сделать следующее.
File b = new File("../some/relative/path");
String absolute = b.getCanonicalPath(); // may throw IOException
или сокращенная запись может быть,
String absolute = new File("../some/relative/path").getCanonicalPath();
Ответ 6
Что лучше, чем просто создание утилиты, которая преобразует относительные пути в абсолютные пути, заключается в создании утилиты, которая преобразует любой путь, переданный ей в абсолютный путь, так что вам не нужно проверять клиентскую сторону.
Следующий код работает для меня в обоих случаях, и я использовал тип String
в сигнатуре метода (оба параметра и возвращаемое значение):
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();
}
Изменение вышеописанного кода для раскрытия типов Path
в сигнатуре метода тривиально (и на самом деле проще), но я думаю, что использование String
в сигнатуре дает большую гибкость.
Ответ 7
Я знаю, что это не лучшее решение, но вы не можете просто объединить подстроку пути fileA от 0 до lastIndexOf("\")
с помощью пути fileB.
Пример A:
-
C:\projects\project1\module7\submodule5\fileA
Пример Bs:
-
..\..\module3\submodule9\subsubmodule32\fileB
C:\projects\project1\module7\submodule5\..\..\module3\submodule9\subsubmodule32\fileB
Если вы не хотите там ..
, это займет больше времени, но я рекомендую пройти путь для fileB
и продолжать брать подстроку от 0 до первого индекса \
. Затем проверьте подстроку. Если это ..
, удалите подстроку и удалите подстроку из fileA's
путь от lastIndexOf(\)
к длине. Затем повторите. Таким образом вы удаляете папки, которые вам не нужны, и ..s
.
Итак:
Пример A:
-
C:\projects\project1\module7\submodule5\fileA
Пример Bs:
Ответ 8
Вот пример кода, который работает для меня.
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();
}
Также я преобразование в относительное:
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");
}
}
Ответ 9
Путь к полному пути Java.
String winPath = downloadPath+"\\"+dir_contents[i].getName();
String absPath = winPath.replace("\\","\\\\");