Golang에서 Mkdir을 사용하여 중첩 된 디렉토리를 만드는 방법은 무엇입니까?


96

'dir1 / dir2 / dir3'과 같은 Go 실행 파일에서 중첩 된 디렉터리 집합을 만들려고합니다. 이 줄을 사용하여 단일 디렉터리를 만드는 데 성공했습니다.

os.Mkdir("." + string(filepath.Separator) + c.Args().First(),0777);

그러나 나는 그 디렉토리 안에 미리 결정된 중첩 디렉토리 세트를 만드는 방법을 모른다.

답변:


181

os.Mkdir단일 디렉토리를 만드는 데 사용됩니다. 폴더 경로를 만들려면 대신 다음을 사용해보십시오.

os.MkdirAll(folderPath, os.ModePerm)

Go 문서

func MkdirAll (path string, perm FileMode) 오류

MkdirAll은 필요한 부모와 함께 path라는 디렉토리를 만들고 nil을 반환합니다. 그렇지 않으면 오류를 반환합니다. 권한 비트 perm은 MkdirAll이 생성하는 모든 디렉토리에 사용됩니다. 경로가 이미 디렉토리 인 경우 MkdirAll은 아무 작업도 수행하지 않고 nil을 반환합니다.

편집하다:

os.ModePerm대신 올바르게 사용하도록 업데이트되었습니다 .
파일 경로를 연결하려면 path/filepath@Chris의 대답에 설명 된대로 package 를 사용하십시오 .


@CodeWarrior : 핑에 감사드립니다. 나는 내 대답을 업데이트하고 Chris
ANisus를 찬성

@chris 감사합니다! :)
Thales P

1
0755및 을 선택할 수 있습니다 os.ModePerm.
updogliu

102

이렇게하면 매직 넘버를 사용할 필요가 없습니다.

os.MkdirAll(newPath, os.ModePerm)

또한 +를 사용하여 경로를 만드는 대신 다음을 사용할 수 있습니다.

import "path/filepath"
path := filepath.Join(someRootPath, someSubPath)

위는 각 플랫폼에서 자동으로 올바른 구분 기호를 사용합니다.


2
이것이 정답입니다. 훨씬 간단하고 플랫폼에 구애받지 않습니다.
Dan Esparza

6

필요한 모든 상위 디렉토리를 만드는 것이 문제인 경우 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_")
...
}

( 이 답변 에서 언급했듯이 합리적인 권한 값을 지정해야합니다. )


3

이를 해결하기 위해 다음과 같은 유틸리티 방법을 사용할 수 있습니다.

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

이것은 동일한 것을 달성하기위한 하나의 대안이지만 두 개의 별개의 "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
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.