webentwicklung-frage-antwort-db.com.de

Relative Pfade in absolute Pfade konvertieren

Ich habe einen absoluten Pfad zu Datei A.

Ich habe einen relativen Pfad zu Datei B aus dem Verzeichnis der Datei A. Dieser Pfad kann und wird ".." verwenden, um die Verzeichnisstruktur auf beliebig komplexe Weise aufzurufen.

Beispiel A:

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

Beispiel Bs:

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

Wie kombiniere ich die beiden, um den einfachsten absoluten Pfad zu Datei B zu erhalten?

30
Tom Tresansky

Wenn ich dein Problem richtig finde, könntest du so etwas tun:

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
40
Fabian Steeg

In Java 7 können Sie auch die Path -Schnittstelle verwenden:

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

String absolutePath = FileSystems.getDefault (). GetPath (mayBeRelativePath) .normalize (). ToAbsolutePath (). ToString ();

7
rssdev10

Versuchen Sie FilenameUtils.normalize() aus Apache commons-io

3
yegor256

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

oder Kurzschreibweise kann sein,

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

2
U.Swap

Was ist besser als nur ein Dienstprogramm zu erstellen, das relative Pfade in absolute Pfade konvertiert, ist das Erstellen eines Dienstprogramms, das jeden an ihn übergebenen Pfad in einen absoluten Pfad umwandelt, sodass Sie nicht auf der Clientseite prüfen müssen.

Der folgende Code funktioniert in beiden Fällen für mich und ich habe den Typ String an der Signatur der Methode verwendet (sowohl Parameter als auch Rückgabewert):

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

Das Ändern des obigen Codes, um Path-Typen für die Signatur der Methode verfügbar zu machen, ist trivial (und eigentlich einfacher), aber ich denke, dass die Verwendung von String für die Signatur mehr Flexibilität bietet.

Hier ist der Beispielcode, der für mich funktioniert.

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

Auch ich habe die Umrechnung relativ:

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

Ich weiß, dass dies nicht die beste Lösung ist, aber Sie können den Teilstring von fileA's Pfad von 0 bis lastIndexOf("\") nicht einfach mit dem fileB-Pfad kombinieren. 

Beispiel A:

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

Beispiel Bs:

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

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

Wenn Sie nicht möchten, dass .. dort ist, dauert es länger, aber ich empfehle, den Pfad für fileB zu durchlaufen und den Teilstring von 0 bis zum ersten Index von \ zu nehmen. Überprüfen Sie dann den Teilstring. Wenn es .. ist, entfernen Sie die Teilzeichenfolge von dort und entfernen Sie die Teilzeichenfolge aus fileA's-Pfad von lastIndexOf(\) bis length. Dann wiederhole es. Auf diese Weise entfernen Sie die nicht benötigten Ordner und den ..s.

So : 

Beispiel A:

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

Beispiel Bs:

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

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

0
Kyra