5

path.Join Considered Harmful

 3 years ago
source link: https://parsiya.net/blog/2019-03-09-path.join-considered-harmful/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Mar 9, 2019 - 2 minute read - Comments - Go

path.Join Considered Harmful

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.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK