Go

Goのpathとfilepathでは動作が異なる Windowsでも正しくパスを扱う

More than 1 year has passed since last update.

goにはパスを操作するパッケージが、標準で pathpath/filepath の2つ有ります。

  • https://golang.org/pkg/path/
    • Package path implements utility routines for manipulating slash-separated paths.
    • スラッシュをセパレータとして常に使用
  • https://golang.org/pkg/path/filepath/
    • Package filepath implements utility routines for manipulating filename paths in a way compatible with the target operating system-defined file paths.
    • システムのセパレータを使用

Base,Dir,Join,Split 等が両方に用意されていますが、ローカルファイルを操作する場合等は filepath の方を使うのがベターです。

サンプルコード

package main

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

func main() {
    fmt.Println("===== Windows Style Path =====")
    winInput := `C:\Windows\System32\drivers\etc\hosts`
    fmt.Println("input: ", winInput)
    fmt.Println("path.Dir: ", path.Dir(winInput))
    fmt.Println("path.Base: ", path.Base(winInput))
    fmt.Println("filepath.Dir: ", filepath.Dir(winInput))
    fmt.Println("filepath.Base: ", filepath.Base(winInput))

    fmt.Println("===== UNIX Style Path =====")
    unixInput := "/etc/hosts"
    fmt.Println("input: ", unixInput)
    fmt.Println("path.Dir: ", path.Dir(unixInput))
    fmt.Println("path.Base: ", path.Base(unixInput))
    fmt.Println("filepath.Dir: ", filepath.Dir(unixInput))
    fmt.Println("filepath.Base: ", filepath.Base(unixInput))
}

https://play.golang.org/p/17MH9zqrub

Linuxでの実行結果

===== Windows Style Path =====
input:  C:\Windows\System32\drivers\etc\hosts
path.Dir:  .
path.Base:  C:\Windows\System32\drivers\etc\hosts
filepath.Dir:  .
filepath.Base:  C:\Windows\System32\drivers\etc\hosts
===== UNIX Style Path =====
input:  /etc/hosts
path.Dir:  /etc
path.Base:  hosts
filepath.Dir:  /etc
filepath.Base:  hosts

Linuxでは path filepath 共に正常な値を取得できます。

Windowsでの実行結果

===== Windows Style Path =====
input:  C:\Windows\System32\drivers\etc\hosts
path.Dir:  .
path.Base:  C:\Windows\System32\drivers\etc\hosts
filepath.Dir:  C:\Windows\System32\drivers\etc
filepath.Base:  hosts
===== UNIX Style Path =====
input:  /etc/hosts
path.Dir:  /etc
path.Base:  hosts
filepath.Dir:  \etc
filepath.Base:  hosts

Windowsでは、 filepath が意図した値を取得できています。