将相对路径转换为绝对路径

我有一个文件A的绝对路径。

我有一个从文件A的目录文件B的相对路径。 该路径可能并将使用“..”以任意复杂的方式上升目录结构。

例A:

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

例B:

  • ..\..\module3\submodule9\subsubmodule32\fileB
  • ..\submodule5\fileB
  • ..\..\module7\..\module4\submodule1\fileB
  • fileB

如何组合这两个以获得文件B 的最简单的绝对路径?

如果我的问题得到解决,你可以这样做:

 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 

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(); 

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

从Apache commons-io尝试FilenameUtils.normalize()

什么比创建一个将相对路径转换为绝对路径的实用程序更好的是创建一个实用程序,将传递给它的任何路径转换为绝对路径,这样您就不必检查客户端。

以下代码在两种情况下都适用于我,并且我在方法的签名处使用了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提供更大的灵活性。

从你的问题来看,如果我能做到正确,你希望从相对路径获得绝对的路径,那么你可以做到以下。

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

或简写符号可以,

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

以下是适合我的示例代码。

  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  0) relativePath.append("..\\\\"); for (index = lastCommonRoot + 1; index  

我知道这不是最好的解决方案,但是你不能只将fileA的路径从0到lastIndexOf("\")的子串与fileB的路径相结合。

例A:

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

例B:

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

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

如果你不想那里的..那么,它需要更长的时间,但我建议通过fileB的路径并继续从0到第一个索引的子串。 然后检查子字符串。 如果是..那么从那里删除子串并从fileA's路径中删除子串从lastIndexOf(\)到length。 然后重复一遍 这样你就可以删除不需要的文件夹和..s

所以:

例A:

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

例B:

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

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

Windows完整Java路径的路径。

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