「dir1/dir2/dir3」などのGo実行可能ファイルからネストされたディレクトリのセットを作成しようとしています。私はこの行で単一のディレクトリを作成することに成功しました:
os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);
ただし、そのディレクトリ内にあらかじめ定義されたネストされたディレクトリセットを作成する方法についてはわかりません。
os.Mkdir
は、単一のディレクトリを作成するために使用されます。フォルダーパスを作成するには、代わりに以下を使用してみてください。
os.MkdirAll(folderPath, os.ModePerm)
func MkdirAll(パス文字列、perm FileMode)エラー
MkdirAllは、必要な親とともにpathという名前のディレクトリを作成し、nilを返すか、エラーを返します。許可ビットpermは、MkdirAllが作成するすべてのディレクトリに使用されます。 pathがすでにディレクトリの場合、MkdirAllは何もせずにnilを返します。
編集:
代わりにos.ModePerm
を正しく使用するように更新されました。
ファイルパスを連結するには、@ Chrisの回答で説明されているように、パッケージpath/filepath
を使用します。
このように、マジックナンバーを使用する必要はありません。
os.MkdirAll(newPath, os.ModePerm)
また、+を使用してパスを作成する代わりに、次を使用できます。
import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)
上記では、各プラットフォームで適切なセパレータが自動的に使用されます。
問題がすべての必要な親ディレクトリを作成することである場合、 os.MkDirAll()
の使用を検討できます。
MkdirAll
は、必要な親とともにpathという名前のディレクトリを作成し、nilを返すか、エラーを返します。
path_test.go は、使用方法の良い例です。
func TestMkdirAll(t *testing.T) {
tmpDir := TempDir()
path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
err := MkdirAll(path, 0777)
if err != nil {
t.Fatalf("MkdirAll %q: %s", path, err)
}
defer RemoveAll(tmpDir + "/_TestMkdirAll_")
...
}
( this answer で述べたように、適切な許可値を指定してください)
これを解決するには、次のようなユーティリティメソッドを使用できます。
import (
"os"
"path/filepath"
"log"
)
func ensureDir(fileName string) {
dirName := filepath.Dir(fileName)
if _, serr := os.Stat(dirName); serr != nil {
merr := os.MkdirAll(dirName, os.ModePerm)
if merr != nil {
panic(merr)
}
}
}
func main() {
_, cerr := os.Create("a/b/c/d.txt")
if cerr != nil {
log.Fatal("error creating a/b/c", cerr)
}
log.Println("created file in a sub-directory.")
}
これは、同じことを達成するための1つの代替手段ですが、2つの別個の「check ..and .. create」操作が原因で発生する競合状態を回避します。
package main
import (
"fmt"
"os"
)
func main() {
if err := ensureDir("/test-dir"); err != nil {
fmt.Println("Directory creation failed with error: " + err.Error())
os.Exit(1)
}
// Proceed forward
}
func ensureDir(dirName string) error {
err := os.MkdirAll(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return nil
} else {
return err
}
}