Credit goes to my friend Stark Riedesel. Check out his github profile. One of these days I will bully him into reviving his blog.
TL;DR: Instead of path.join use filepath.Join.
What's Wrong with path.Join?
path.Join joins a bunch of paths together. Problem is, it uses /
as separator regardless of operating system. We can see it in its source at https://golang.org/src/path/path.go?s=4034:4066#L145:
func Join(elem ...string) string {
for i, e := range elem {
if e != "" {
return Clean(strings.Join(elem[i:], "/")) // <---
}
}
return ""
}
This is problematic on Windows where your paths (or some of them) use \
as separators. Consider this minimal example Go playground link:
package main
import (
"fmt"
"path"
)
func main() {
// Create the path to the hosts file.
path1 := "c:\\windows\\system32"
path2 := "drivers\\etc\\hosts"
fmt.Println(path.Join(path1, path2))
}
You would expect it to create the correct path. Instead, you get:
c:\windows\system32/drivers\etc\hosts
What Should We Use Instead?
Use filepath.Join instead. It uses OS specific separators.
Note 1: If you modify the example on the playground to filepath.Join
you still get the same result. Obviously, Go playground is not running on Windows.
Note 2: Alternatively, you could convert all paths to use /
as the separator. c:/windows/system32/drivers/etc/hosts
is an acceptable Windows path. This is what I did in borrowed time after Stark told me about this issue.