Golang'da Mkdir kullanarak iç içe dizinler nasıl oluşturulur?


97

'Dir1 / dir2 / dir3' gibi bir Go yürütülebilir dosyasından iç içe geçmiş dizinler kümesi oluşturmaya çalışıyorum. Bu satırla tek bir dizin oluşturmayı başardım:

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

Bununla birlikte, bu dizinin içinde önceden belirlenmiş iç içe dizinler kümesi oluşturmaya nasıl yaklaşacağım konusunda hiçbir fikrim yok.

Yanıtlar:


182

os.Mkdirtek bir dizin oluşturmak için kullanılır. Bir klasör yolu oluşturmak için bunun yerine şunu kullanmayı deneyin:

os.MkdirAll(folderPath, os.ModePerm)

Belgelere git

func MkdirAll (yol dizesi, perm FileMode) hatası

MkdirAll, gerekli üst öğelerle birlikte yol adında bir dizin oluşturur ve nil döndürür, yoksa bir hata döndürür. İzin bitleri, MkdirAll'ın oluşturduğu tüm dizinler için kullanılır. Yol zaten bir dizinse, MkdirAll hiçbir şey yapmaz ve nil değerini döndürür.

Düzenle:

os.ModePermBunun yerine doğru kullanım için güncellendi .
Dosya yollarının birleştirilmesi için, path/filepath@Chris'in yanıtında açıklandığı gibi paketi kullanın .


@CodeWarrior: Ping için teşekkürler. Cevabımı güncelledim ve Chris
ANisus

Teşekkür ederim @chris! :)
Thales P

1
0755Ve arasında seçim yapmak isteyebilirsiniz os.ModePerm.
updogliu

103

Bu şekilde herhangi bir sihirli sayı kullanmak zorunda kalmazsınız:

os.MkdirAll(newPath, os.ModePerm)

Ayrıca, yollar oluşturmak için + kullanmak yerine şunları kullanabilirsiniz:

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

Yukarıdakiler, sizin için her platformda otomatik olarak doğru ayırıcıları kullanır.


3
Bu doğru cevap. Çok daha basit ve platformdan bağımsız.
Dan Esparza

6

Sorun, gerekli tüm ana dizinleri oluşturmaksa, kullanmayı düşünebilirsiniz. os.MkDirAll()

MkdirAll gerekli ebeveynlerle birlikte yol adında bir dizin oluşturur ve nil değerini döndürür, aksi takdirde bir hata döndürür.

Path_test.go nasıl kullanılacağını iyi bir örnektir:

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_")
...
}

( Bu cevapta belirtildiği gibi makul bir izin değeri belirlediğinizden emin olun )


3

Bunu çözmek için aşağıdaki gibi bir yardımcı yöntem kullanılabilir.

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

Bu, aynı şeyi başarmak için bir alternatiftir, ancak iki farklı "kontrol et .. ve .. oluştur" işleminin neden olduğu yarış koşullarını önler.

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
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.