Ошибка io.ErrShortWrite
Ошибка io.ErrShortWrite возвращается функциями и методами записи в пакете io,
когда фактически записанное количество байт меньше запрошенного.
Эта ошибка сигнализирует о том, что запись не была полностью выполнена,
и вызывающий код должен обработать эту ситуацию. Обычно такая ошибка
возникает при работе с файловыми системами, сетевыми соединениями
или другими потоками данных, где запись может быть ограничена
доступным пространством или другими факторами.
Синтаксис
io.ErrShortWrite
Пример использования с файлом
В следующем примере создается файл, и выполняется попытка
записи большого объема данных. Если запись завершилась
не полностью, возвращается ошибка io.ErrShortWrite:
package 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
может возникнуть, если буфер не может быть полностью записан
в нижележащий поток. Рассмотрим пример:
package 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())
}
Результат выполнения кода:
"Successfully wrote 39 bytes"
"Content: This is a test string for bufio writer"
Пример обработки короткой записи
В реальных приложениях важно корректно обрабатывать ситуацию короткой записи. В следующем примере реализована функция, которая повторяет попытки записи до полного успеха или достижения лимита попыток:
package 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.
Первая возникает при недостаточной записи, вторая - при достижении
конца файла при чтении. Рассмотрим пример, демонстрирующий
различные типы ошибок:
package 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,
который записывает строку в файл