Jak sprawdzić, czy plik lub katalog istnieje?


133

Chcę sprawdzić istnienie pliku ./conf/app.iniw moim kodzie Go, ale nie mogę znaleźć dobrego sposobu, aby to zrobić.

Wiem, że istnieje metoda File w Javie:, public boolean exists()która zwraca prawdę, jeśli plik lub katalog istnieje.

Ale jak można to zrobić w Go?


7
Pamiętaj też, że w zależności od tego, jak zamierzasz wykorzystać te informacje, masz stan wyścigu. Wszystko, co możesz powiedzieć, to to, że jakiś czas temu plik istniał / nie istniał; zanim zaczniesz działać na teście, może być odwrotnie. Zwykle znacznie lepiej jest sprawdzić, wykonując dowolną operację, którą zamierzasz wykonać (np. Nie sprawdzaj przed otwarciem istniejącego lub utworzeniem nowego pliku, ale zrób f, err := os.Open(name)lub, f, err := os.OpenFile(name,os.O_CREATE|os.O_EXCL, mode)a następnie sprawdź os.IsNotExist(err)).
Dave C

Odpowiedzi:


195
// exists returns whether the given file or directory exists
func exists(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil { return true, nil }
    if os.IsNotExist(err) { return false, nil }
    return false, err
}

Edytowano, aby dodać obsługę błędów.


4
Dla mnie wygląda to na „programowanie wyjątków”. Czy jest jakiś zasób, który uzasadnia ten rodzaj kodu jako oficjalny paradygmat #golang?
Olivier Amblet

22
@OlivierAmblet Nie ma tutaj wyjątku. Go używa panicdla rzeczywistego obiektu typu „wyjątek”. Możesz „złapać” telefonem do recover. Jawne zwracanie errjako drugiej wartości zwracanej jest niezwykle powszechną, idiomatyczną techniką Go. Zobacz: golang.org/doc/effective_go.html#errors
Chris Pfohl

13
rozwiązanie nie jest zbyt trudne, idź jest wyjątkowe
zhaozhi

1
Prawdą jest, że nie ma funkcji logicznej Exists, ale kod aplikacji może być prostszy, jeśli chcesz tylko sprawdzić istnienie pliku:if _, err := os.Stat("./conf/app.ini"); err == nil { /*exists*/ } else { /*not exists or some other error*/ }
Tobia

11
Dlaczego wszystko w tym języku jest takie skomplikowane?
Top Cat


23

Bardziej do Twojej wiadomości, ponieważ rozejrzałem się przez kilka minut, myśląc, że moje pytanie będzie szybko odszukane.

Jak sprawdzić, czy ścieżka reprezentuje istniejący katalog w Go?

To była najpopularniejsza odpowiedź w moich wynikach wyszukiwania, ale tutaj i gdzie indziej rozwiązania zapewniają jedynie sprawdzenie istnienia. Aby sprawdzić, czy pathreprezentuje istniejący katalog, stwierdziłem, że mogę łatwo:

path := GetSomePath();
if stat, err := os.Stat(path); err == nil && stat.IsDir() {
    // path is a directory
}

Część mojego problemu polegała na tym, że spodziewałem się, że path/filepathpakiet będzie zawierał funkcję isDir ().


13

Prosty sposób sprawdzenia, czy plik istnieje, czy nie:

if _, err := os.Stat("/path/to/whatever"); os.IsNotExist(err) {
    // path/to/whatever does not exist
}

if _, err := os.Stat("/path/to/whatever"); err == nil {
    // path/to/whatever exists
}

Źródła:


Gdybym ci powiedział: „Prosty sposób na szybkie wzbogacenie się: wpłać pieniądze do banku. Weź pieniądze z banku”. można by pomyśleć, że mówiłem ci, że potrzebne są dwa kolejne kroki zamiast dwóch alternatywnych. Problem z tą odpowiedzią polega na tym, że czytelnicy mogą nie rozumieć, że sugerujesz dwa różne możliwe podejścia.
kfsone

0

Używam następującej funkcji, aby sprawdzić moje katalogi pod kątem błędów. Jest bardzo podobny do poprzednich odpowiedzi, ale myślę, że brak zagnieżdżenia ifs sprawia, że ​​kod jest bardziej przejrzysty. Używa go-homedirdo usuwania ~ze ścieżek katalogów i pkg/errorszwracania ładniejszych komunikatów o błędach, ale byłoby łatwo je usunąć, jeśli nie potrzebujesz ich funkcjonalności.

// validateDirectory expands a directory and checks that it exists
// it returns the full path to the directory on success
// validateDirectory("~/foo") -> ("/home/bbkane/foo", nil)
func validateDirectory(dir string) (string, error) {
    dirPath, err := homedir.Expand(dir)
    if err != nil {
        return "", errors.WithStack(err)
    }
    info, err := os.Stat(dirPath)
    if os.IsNotExist(err) {
        return "", errors.Wrapf(err, "Directory does not exist: %v\n", dirPath)
    }
    if err != nil {
        return "", errors.Wrapf(err, "Directory error: %v\n", dirPath)

    }
    if !info.IsDir() {
        return "", errors.Errorf("Directory is a file, not a directory: %#v\n", dirPath)
    }
    return dirPath, nil
}

Ponadto, aby powtórzyć komentarz @Dave C, jeśli powodem, dla którego sprawdzasz istnienie katalogu, jest zapisanie w nim pliku, zwykle lepiej po prostu spróbować po prostu spróbować otworzyć go później, aby rozwiązać problem z błędami:

// O_EXCL - used with O_CREATE, file must not exist
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
if err != nil {
    return errors.WithStack(err)
}
defer file.Close()

-3

Istnieje prosty sposób sprawdzenia, czy plik istnieje, czy nie:

if _, err := os.Stat("./conf/app.ini"); err != nil {
    if os.IsNotExist(err) {
        ..... //Shows error if file not exists
    } else {
       ..... // Shows success message like file is there
    }
}

To jest duplikat odpowiedzi Denysa Ségureta.
StardustGogeta

Oprócz tego, że jest duplikatem, który musiał zostać naprawiony przez redaktora, jest to również błąd. Nigdy nie obsługuje przypadku, w którym istnieje plik.
kfsone
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.