Ошибка io.ErrUnexpectedEOF
Ошибка io.ErrUnexpectedEOF возникает, когда операция чтения не может
прочитать запрошенное количество байт, хотя поток данных еще не достиг
конечной метки EOF. В отличие от обычной ошибки io.EOF,
которая означает корректное завершение чтения, данная ошибка свидетельствует
о том, что данные повреждены или оборваны преждевременно. Особенно часто
с этой ошибкой сталкиваются при работе с бинарными форматами данных,
архивами, сетевыми протоколами или любыми структурированными данными,
где четко определены размеры блоков.
Например, если вы пытаетесь прочитать из файла структуру фиксированного
размера, а файл неожиданно обрывается посередине, то функция чтения
вернет именно эту ошибку. Первым параметром функции чтения выступает
сам объект io.Reader, из которого происходит чтение, а вторым -
байтовый срез, в который считываются данные.
Синтаксис
func Read(r io.Reader, buf []byte) (int, error)
Пример возникновения ошибки io.ErrUnexpectedEOF
Давайте рассмотрим ситуацию, когда мы пытаемся прочитать из файла ровно 100 байт, но файл содержит только 50 байт:
package main
import (
"fmt"
"io"
"os"
)
func main() {
data := []byte("short file")
os.WriteFile("test.txt", data, 0644)
file, err := os.Open("test.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
buf := make([]byte, 100)
n, err := io.ReadFull(file, buf)
if err != nil {
fmt.Printf("Read bytes: %d, Error: %v\n", n, err)
return
}
fmt.Printf("Successfully read %d bytes\n", n)
}
Результат выполнения кода:
"Read bytes: 10, Error: unexpected EOF"
Пример проверки на io.ErrUnexpectedEOF
Рассмотрим, как правильно обрабатывать ошибку и отличать ее от корректного конца файла:
package main
import (
"errors"
"fmt"
"io"
"os"
)
func main() {
data := []byte("abcde")
os.WriteFile("test.txt", data, 0644)
file, err := os.Open("test.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
buf := make([]byte, 3)
_, err = io.ReadFull(file, buf)
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) {
fmt.Println("File is truncated: unexpected EOF")
} else if errors.Is(err, io.EOF) {
fmt.Println("End of file reached correctly")
} else {
fmt.Println("Other error:", err)
}
return
}
fmt.Println("Data read successfully:", string(buf))
}
Результат выполнения кода:
"Data read successfully: abc"
Пример использования io.ReadAtLeast
Функция io.ReadAtLeast также может вернуть ошибку
io.ErrUnexpectedEOF, если не удалось прочитать минимальное
количество байт:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
reader := strings.NewReader("hello")
buf := make([]byte, 10)
n, err := io.ReadAtLeast(reader, buf, 5)
if err != nil {
fmt.Printf("Read %d bytes, Error: %v\n", n, err)
return
}
fmt.Printf("Read %d bytes: %s\n", n, string(buf[:n]))
}
Результат выполнения кода:
"Read 5 bytes, Error: unexpected EOF"
Смотрите также
-
функцию
io.ReadFull,
которая читает ровно заданное количество байт -
функцию
io.ReadAtLeast,
которая читает как минимум указанное количество байт -
ошибку
io.EOF,
которая возникает при корректном окончании чтения -
функцию
os.File.Read,
которая читает данные из открытого файла