Home > Software design >  Is there a function that returns the absolute path from a path that is relative to another?
Is there a function that returns the absolute path from a path that is relative to another?

Time:01-09

I need to be able to work out where a file is based on the path used in a different file. It's probably just better to use an example:

This is the directory structure:

/
  foo
    bar.txt
    text.txt
  bar
    main.go

In the text.txt file, bar.txt is referenced with ./bar.txt which works but if I try and find the absolute path of ./bar.txt from main.go with filepath.Abs("./bar.txt") then it will return /bar/bar.txt because it assumes that . is the current working directory.

From the documentation: Abs returns an absolute representation of path. If the path is not absolute it will be joined with the current working directory to turn it into an absolute path.

My question is how do I get the absolute path of ./bar.txt when . is realtive to text.txt.

Sorry for this question being probably overcomplicated but I couldn't come up with a better way of showing an example.

CodePudding user response:

I don't know exactly maybe there is an easier way to find the absolute path using go stdlib. You can use the following piece of code for the solution.

It gets the content from the first file (text.txt) then checks if the path is already absolute path and if it is absolute it does nothing but if it is not absolute path then it finds absolute path based on text.txt file.

package main

import (
    "fmt"
    "os"
    "path"
    "path/filepath"
)

func main() {
    var new_abs_path string
    var text_file = "./foo/text.txt"

    b, err := os.ReadFile(text_file)
    check(err)

    new_file_path := string(b)

    if filepath.IsAbs(new_file_path) {
        new_abs_path = new_file_path
    } else {
        text_abs, err := filepath.Abs(text_file)
        check(err)
        
        new_abs_path, err = filepath.Abs(path.Join(path.Dir(text_abs), new_file_path))
        check(err)
    }
    fmt.Println(new_abs_path)
}

func check(err error) {
    if err != nil {
        panic(err)
    }
}


CodePudding user response:

This answer is almost there but I managed to modify it to work for me.

func getAbs(path string, locationPath string) string {
    new_file_path := path
    new_abs_path := path
    if filepath.IsAbs(new_file_path) {
        new_abs_path = new_file_path
    } else {
        new_abs_path, _ = filepath.Abs(filepath.Join(locationPath, path))
        fmt.Println(new_abs_path, locationPath)
    }
    return new_abs_path
}

This works by just adding the path to the file to the directory that the file that references it is in.

For example:

fmt.Println(getAbs("./bar.txt", "/foo")) //foo is the directory that text.txt is in which references bar.txt is in
  • Related