Ошибка io.ErrShortWrite

Ошибка io.ErrShortWrite возвращается функциями и методами записи в пакете io, когда фактически записанное количество байт меньше запрошенного. Эта ошибка сигнализирует о том, что запись не была полностью выполнена, и вызывающий код должен обработать эту ситуацию. Обычно такая ошибка возникает при работе с файловыми системами, сетевыми соединениями или другими потоками данных, где запись может быть ограничена доступным пространством или другими факторами.

Синтаксис

goio.ErrShortWrite

Пример использования с файлом

В следующем примере создается файл, и выполняется попытка записи большого объема данных. Если запись завершилась не полностью, возвращается ошибка io.ErrShortWrite:

gopackage main

import (
  "fmt"
  "io"
  "os"
)

func main() {
  file, err := os.Create("example.txt")
  if err != nil {
    fmt.Println("Error creating file:", err)
    return
  }
  defer file.Close()

  data := []byte("Hello, World! This is a test string.")
  n, err := file.Write(data)
  if err != nil {
    if err == io.ErrShortWrite {
      fmt.Printf("Short write: wrote %d of %d bytes\n", n, len(data))
    } else {
      fmt.Println("Write error:", err)
    }
    return
  }

  fmt.Printf("Successfully wrote %d bytes\n", n)
}

Пример с буферизированным писателем

При работе с bufio.Writer ошибка io.ErrShortWrite может возникнуть, если буфер не может быть полностью записан в нижележащий поток. Рассмотрим пример:

gopackage main

import (
  "bufio"
  "fmt"
  "io"
  "strings"
)

func main() {
  var b strings.Builder
  writer := bufio.NewWriter(&b)

  data := []byte("This is a test string for bufio writer")
  n, err := writer.Write(data)
  if err != nil {
    if err == io.ErrShortWrite {
      fmt.Printf("Short write in buffer: wrote %d of %d bytes\n", n, len(data))
    } else {
      fmt.Println("Buffer write error:", err)
    }
    return
  }

  err = writer.Flush()
  if err != nil {
    fmt.Println("Flush error:", err)
    return
  }

  fmt.Printf("Successfully wrote %d bytes\n", n)
  fmt.Println("Content:", b.String())
}

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

go"Successfully wrote 39 bytes"
"Content: This is a test string for bufio writer"

Пример обработки короткой записи

В реальных приложениях важно корректно обрабатывать ситуацию короткой записи. В следующем примере реализована функция, которая повторяет попытки записи до полного успеха или достижения лимита попыток:

gopackage main

import (
  "fmt"
  "io"
  "os"
)

func writeFull(w io.Writer, data []byte) error {
  written := 0
  maxAttempts := 3

  for attempts := 0; attempts < maxAttempts; attempts++ {
    n, err := w.Write(data[written:])
    if err != nil {
      if err == io.ErrShortWrite {
        written += n
        fmt.Printf("Attempt %d: wrote %d bytes, total %d of %d\n",
          attempts+1, n, written, len(data))
        continue
      }
      return err
    }
    written += n
    if written == len(data) {
      return nil
    }
  }
  return fmt.Errorf("failed to write full data after %d attempts: wrote %d of %d bytes",
    maxAttempts, written, len(data))
}

func main() {
  file, err := os.Create("full_write.txt")
  if err != nil {
    fmt.Println("Error creating file:", err)
    return
  }
  defer file.Close()

  data := []byte("Data that must be written completely to the file")
  err = writeFull(file, data)
  if err != nil {
    fmt.Println("Write failed:", err)
    return
  }

  fmt.Println("All data written successfully")
}

Сравнение с io.EOF

Важно различать ошибку io.ErrShortWrite и io.EOF. Первая возникает при недостаточной записи, вторая - при достижении конца файла при чтении. Рассмотрим пример, демонстрирующий различные типы ошибок:

gopackage main

import (
  "fmt"
  "io"
  "os"
)

func main() {
  file, err := os.Open("non_existent_file.txt")
  if err != nil {
    fmt.Println("Open error:", err)
    return
  }
  defer file.Close()

  data := make([]byte, 1024)
  n, err := file.Read(data)
  if err != nil {
    if err == io.EOF {
      fmt.Println("Reached end of file")
    } else {
      fmt.Println("Read error:", err)
    }
    return
  }

  fmt.Printf("Read %d bytes\n", n)
}

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

  • ошибку io.EOF,
    которая возникает при достижении конца файла
  • ошибку io.ErrUnexpectedEOF,
    которая возникает при неожиданном конце файла
  • метод os.File.Write,
    который записывает данные в файл
  • метод os.File.WriteString,
    который записывает строку в файл