'dir1 / dir2 / dir3'などのGo実行可能ファイルから一連のネストされたディレクトリを作成しようとしています。私はこの行で単一のディレクトリを作成することに成功しました:
os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);
ただし、そのディレクトリ内に、事前に定義されたネストされたディレクトリのセットを作成する方法はわかりません。
回答:
os.Mkdir
単一のディレクトリを作成するために使用されます。フォルダパスを作成するには、代わりに次を使用してみてください:
os.MkdirAll(folderPath, os.ModePerm)
func MkdirAll(path string、perm FileMode)エラー
MkdirAllは、必要な親とともに、pathという名前のディレクトリを作成し、nilを返すか、そうでなければエラーを返します。許可ビットpermは、MkdirAllが作成するすべてのディレクトリに使用されます。pathがすでにディレクトリの場合、MkdirAllは何もせずnilを返します。
編集:
os.ModePerm
代わりに正しく使用するように更新されました。
ファイルパスを連結するにpath/filepath
は、@ Chrisの回答に記載されているパッケージを使用します。
0755
との間で選択することができますos.ModePerm
。
これにより、マジックナンバーを使用する必要がなくなります。
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_")
...
}
(この回答で述べられているように、賢明な許可値を必ず指定してください)
これを解決するには、次のようなユーティリティメソッドを使用できます。
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
}
}