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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3204955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:24:35  来源:igfitidea点击:

Converting Relative Paths to Absolute Paths

javapath

提问by Tom Tresansky

I have an absolute path to file A.

我有文件 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.

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

Example A:

示例 A:

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

Example Bs:

示例 B:

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

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

如何将两者结合起来以获得文件 B的最简单的绝对路径?

采纳答案by Fabian Steeg

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

回答by Kyra

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.

我知道这不是最好的解决方案,但您不能将 fileA 路径的子字符串从 0 到lastIndexOf("\")fileB 的路径。

Example A:

示例 A:

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

Example Bs:

示例 B:

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

C:\projects\project1\module7\submodule5\..\..\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 fileBand 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'spath from lastIndexOf(\)to length. Then repeat. That way you are removing the folders you don't need and the ..s.

如果您不希望..在那里,则需要更长的时间,但我建议通过路径fileB并继续将子字符串从 0 到\. 然后检查子字符串。如果是..,则从那里删除子字符串并将子字符串从fileA's路径中删除lastIndexOf(\)到长度。然后重复。这样您就可以删除不需要的文件夹和..s.

So :

所以 :

Example A:

示例 A:

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

Example Bs:

示例 B:

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

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

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

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

回答by iviorel

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");
        }            
    }

回答by yegor256

回答by onlyhuman

In Java 7you can also use the Pathinterface:

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

回答by Marcus Junius Brutus

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 Stringtype at the signature of the method (both parameter and return value):

下面的代码在这两种情况下都适用于我,我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();
}

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

更改上面的代码以Path在方法签名上公开类型是微不足道的(实际上更容易),但我认为String在签名上使用提供了更大的灵活性。

回答by Ravi

Windows path to full Java path.

到完整 Java 路径的 Windows 路径。

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

回答by rssdev10

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

回答by U.Swap

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