mkdir, якщо не існує, використовуючи golang


83

Я вивчаю golang (початківець), і я шукав як на google, так і на stackoverflow, але я не міг знайти відповіді, тому вибачте мене, якщо вже про це запитали, але як я можу mkdir, якщо в golang не існує.

Наприклад, у вузлі я б використовував fs-extra з функцією secureDirSync (якщо блокування, звичайно, не турбує)

fs.ensureDir("./public");

Відповіді:


142

Я натрапив на два шляхи:

  1. Перевірте наявність каталогу та створіть його, якщо він не існує:

    if _, err := os.Stat(path); os.IsNotExist(err) {
        os.Mkdir(path, mode)
    }
    
  2. Спробуйте створити каталог та ігнорувати будь-які проблеми:

    _ = os.Mkdir(path, mode)
    

33
Для тих, хто цікавиться, що таке змінна mode, дивіться: golang.org/pkg/os/#FileMode . Ви, мабуть, хочете використовувати os.ModeDirяк його значення.
Невідомий розробник

5
Також для тих, хто задається питанням про mode, ви можете скористатися, os.Mkdir("dirname", 0700)якщо хочете мати можливість писати в цей каталог з тієї самої програми, див. Це для більш докладної інформації.
Хайро Лозано

3
Чому ми ігноруємо будь-які проблеми, коли робимо os.Mkdir ()?
Giannis

@Giannis Помилка, якщо вона вже існує, це нормально. Можливо, не рекомендується.
472084

1
При створенні каталогу для зберігання файлів у режимі os.ModeDir. У нового каталогу недостатньо дозволів. Я виявив, що os.ModePermпрацював лише у мене. Що еквівалентно 0777або drwxr-xr-x. Я думаю, що дозволи можуть бути трохи нижчими, але я 0666не зробив трюку.
Джастін

145

Гаразд, я зрозумів це завдяки цьому питанню / відповіді

import(
    "os"
    "path/filepath"
)

newpath := filepath.Join(".", "public")
os.MkdirAll(newpath, os.ModePerm)

MkdirAll створює каталог з іменем path, разом з усіма необхідними батьками, і повертає nil, або повертає файлerror .


5
Це найкраща відповідь і використовується stdlib. Це особливо корисно, коли використовується поряд з os.Create, де вам також може знадобитися створити піддиректорії (використання filepath.Dir("path/to/file")повного шляху до файлу - це хороший підхід на мої очі
Падді

6
Можливо, ви захочете перевірити відповідь на помилку у виклику MkdirAll, наприклад: `if err: = os.MkdirAll (" / somepath / ", os.ModeDir); помилка! = nil {fmt.Println ("Не вдається створити прихований каталог.")} `
Пол А. Фортін,

7

Ви можете використовувати, os.Statщоб перевірити, чи існує заданий шлях.
Якщо цього не сталося, ви можете використовувати його os.Mkdirдля створення.


2

Це одна з альтернатив для досягнення того самого, але вона дозволяє уникнути перегонових умов, спричинених двома різними операціями "перевірка .. та .. створення".

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.Mkdir(dirName, os.ModeDir)

    if err == nil || os.IsExist(err) {
        return nil
    } else {
        return err
    }
}

Хоча ваш код може дати відповідь на запитання, додайте контекст навколо нього, щоб інші мали певне уявлення про те, що він робить і чому він там.
Тео,

0

Отже, я знайшов, що працює для мене:

//Get the base file dir
path, err := os.Getwd()
if err != nil {
    log.Println("error msg", err)
}

//Create output path
outPath:= filepath.Join(path, "output")

//Create dir output using above code
if _, err := os.Stat(outPath); os.IsNotExist(err) {
    os.Mkdir(outPath, 0755)
}

Мені подобається портативність цього.


0

Або ви можете спробувати створити файл і перевірити, чи повернута помилка не є помилкою "файл існує"

if err := os.Mkdir(path, mode); err != nil && !os.IsExist(err) {
    log.Fatal(err)
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.