Ошибка fs.ErrExist

Ошибка fs.ErrExist возникает при попытке создать файл или директорию, которая уже существует. Эта ошибка возвращается функциями пакета os при работе с файловой системой, когда операция создания невозможна из-за того, что целевой объект уже присутствует в файловой системе. Ошибка используется для проверки существования файла перед его созданием.

Синтаксис

goerr := error // ошибка, возвращаемая функциями fs
if errors.Is(err, fs.ErrExist) {
  // обработка ситуации, когда файл уже существует
}

Ошибка fs.ErrExist является переменной уровня пакета и имеет тип error. Для проверки наличия этой ошибки следует использовать функцию errors.Is, которая корректно работает с обертками ошибок, в отличие от прямого сравнения через оператор ==.

Пример

Давайте попробуем создать файл, который уже существует, и обработаем ошибку:

gopackage main

import (
  "errors"
  "fmt"
  "os"
)

func main() {
  filename := "example.txt"
  
  // Создаем файл первый раз
  file, err := os.Create(filename)
  if err != nil {
    fmt.Println("Error creating file:", err)
    return
  }
  file.Close()
  
  // Пытаемся создать файл снова
  file, err = os.Create(filename)
  if err != nil {
    if errors.Is(err, fs.ErrExist) {
      fmt.Println("File already exists")
    } else {
      fmt.Println("Other error:", err)
    }
    return
  }
  defer file.Close()
}

Результат выполнения кода:

go"File already exists"

Пример

Давайте рассмотрим проверку существования директории перед ее созданием:

gopackage main

import (
  "errors"
  "fmt"
  "os"
)

func main() {
  dirName := "testdir"
  
  // Пытаемся создать директорию
  err := os.Mkdir(dirName, 0755)
  if err != nil {
    if errors.Is(err, fs.ErrExist) {
      fmt.Println("Directory already exists")
    } else {
      fmt.Println("Other error:", err)
    }
    return
  }
  fmt.Println("Directory created successfully")
  
  // Пытаемся создать директорию повторно
  err = os.Mkdir(dirName, 0755)
  if err != nil {
    if errors.Is(err, fs.ErrExist) {
      fmt.Println("Directory already exists")
    } else {
      fmt.Println("Other error:", err)
    }
  }
}

Результат выполнения кода:

go"Directory created successfully"
"Directory already exists"

Пример

Давайте рассмотрим использование флага os.O_EXCL для атомарной проверки существования файла:

gopackage main

import (
  "errors"
  "fmt"
  "os"
)

func main() {
  filename := "exclusive.txt"
  
  // Пытаемся создать файл с флагом O_EXCL
  file, err := os.OpenFile(
    filename,
    os.O_CREATE|os.O_EXCL|os.O_WRONLY,
    0644,
  )
  if err != nil {
    if errors.Is(err, fs.ErrExist) {
      fmt.Println("File already exists")
    } else {
      fmt.Println("Other error:", err)
    }
    return
  }
  defer file.Close()
  
  file.WriteString("This file was created exclusively")
  fmt.Println("File created successfully")
}

Результат выполнения кода:

go"File created successfully"

При повторном запуске программы будет выведено сообщение о том, что файл уже существует.

Смотрите также

  • ошибку os.ErrExist,
    которая является аналогом для работы с функциями пакета os
  • функцию os.IsExist,
    которая проверяет, является ли ошибка ошибкой существования
  • ошибку fs.ErrNotExist,
    которая указывает на отсутствие файла или директории
  • функцию os.Stat,
    которая проверяет существование файла без его открытия