2015-10-31 2 views
26

Я новичок в Go и не могу найти способ удалить все содержимое каталога, когда я не знаю содержимого.Golang удалить все содержимое каталога

Я пробовал:

os.RemoveAll("/tmp/*") 
os.Remove("/tmp/*") 

но получить remove *: no such file or directory или invalid argument.

И, конечно, если вы:

os.RemoveAll("/tmp/") 

удаляет каталог tmp, а также. Это не то, что я хочу.

+0

Из-за того, что вы используете командные команды для этого и вызываете os.Exec. – 0x434D53

+2

@ 0x434D53: Команды командной оболочки зависят от ОС и оболочки. Используйте Go package 'os' OS и независимые от оболочки функции для переносимости. Например, я протестировал решение Go на Linux и Windows. – peterSO

+1

Ofc они есть. Было просто дополнительным предложением, которое могло бы соответствовать его усечению. По какой-то причине я не написал это как ответ. – 0x434D53

ответ

18

Напишите простую функцию RemoveContents. Например,

package main 

import (
    "fmt" 
    "os" 
    "path/filepath" 
    "strings" 
) 

func RemoveContents(dir string) error { 
    d, err := os.Open(dir) 
    if err != nil { 
     return err 
    } 
    defer d.Close() 
    names, err := d.Readdirnames(-1) 
    if err != nil { 
     return err 
    } 
    for _, name := range names { 
     err = os.RemoveAll(filepath.Join(dir, name)) 
     if err != nil { 
      return err 
     } 
    } 
    return nil 
} 

func main() { 
    dir := strings.TrimSuffix(filepath.Base(os.Args[0]), filepath.Ext(os.Args[0])) 
    dir = filepath.Join(os.TempDir(), dir) 
    dirs := filepath.Join(dir, `tmpdir`) 
    err := os.MkdirAll(dirs, 0777) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    file := filepath.Join(dir, `tmpfile`) 
    f, err := os.Create(file) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    f.Close() 
    file = filepath.Join(dirs, `tmpfile`) 
    f, err = os.Create(file) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
    f.Close() 

    err = RemoveContents(dir) 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 
} 
+0

спасибо за это, я действительно пошел с чем-то похожим, но с помощью 'ioutil.ReadDir', чтобы сохранить открытие каталога. Спасибо – mattl

+2

@mattl: Это не хорошо. Для пакета 'os', [Readdirnames] (https://golang.org/pkg/os/#File.Readdirnames) читает и возвращает кусочек имен из каталога." Для пакета 'ioutil', [ReadDir] (https://golang.org/pkg/io/ioutil/#ReadDir) читается каталог с именем dirname и возвращает список отсортированных записей каталога." Переходя от 'os' к' ioutil', вы добавили ненужный вид списка имен: ['func ReadDir'] (https://golang.org/src/io/ioutil/ioutil.go):' sort.Sort (кличка (список)) '. – peterSO

+0

Стоит отметить спасибо – mattl

30

Это может быть глупый ответ, но почему бы просто не сделать?

os.RemoveAll("/tmp/") 
os.MkdirAll("/tmp/",FileMode) 
+0

Я не уверен, либо он не существовал, когда поднимался этот вопрос, или он делал что-то неожиданное. – mattl

+0

Это, скорее всего, существовало, когда он говорил о removeall, поэтому он может сделать что-то неожиданное, но я хотел бы знать, как часто пользуюсь этим методом. – Lomithrani

+0

@Lomithrani RemoveAll говорит, что он выходит из первого столкновения с ошибкой. Индивидуальное удаление каждого файла позволит вам удалить больше в случае, когда ожидается несколько ошибок. Это все, что я мог придумать после прочтения документации. – anon58192932