Интерфейс io.WriterAt
Интерфейс io.WriterAt предназначен для записи данных в поток,
начиная с заданного смещения. Основной метод интерфейса -
WriteAt, который принимает срез байт и позицию в файле
(смещение) для записи. В отличие от обычного io.Writer,
который пишет данные в текущую позицию файла, WriterAt
позволяет записывать данные в произвольное место, не затрагивая
остальное содержимое. Метод возвращает количество записанных байт
и ошибку, если она произошла.
Синтаксис
type WriterAt interface {
WriteAt(p []byte, off int64) (n int, err error)
}
В метод WriteAt первым аргументом передается срез байт,
который содержит данные для записи. Вторым аргументом передается
смещение в байтах от начала файла, куда будут записаны данные.
Пример
Продемонстрируем работу io.WriterAt на примере с файлом.
Откроем файл для записи с помощью os.OpenFile с флагом
os.O_RDWR. Затем запишем данные в середину файла, используя
метод WriteAt:
package main
import (
"fmt"
"io"
"os"
)
func main() {
// Открываем файл для чтения и записи
file, err := os.OpenFile("example.txt", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
defer file.Close()
// Записываем начальные данные
file.WriteString("Hello, World!")
// Записываем в позицию 7 строку "Go"
_, err = file.WriteAt([]byte("Go"), 7)
if err != nil {
panic(err)
}
// Читаем обновленное содержимое
file.Seek(0, io.SeekStart)
data, _ := io.ReadAll(file)
fmt.Println(string(data))
}
Результат выполнения кода:
"Hello, GoWorld!"
Пример
Рассмотрим случай, когда мы хотим записать данные за пределами
текущего размера файла. Метод WriteAt автоматически
расширит файл при необходимости. Обратите внимание, что если
смещение больше размера файла, между концом файла и позицией
записи будут нулевые байты:
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("example2.txt", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
defer file.Close()
// Записываем данные на позицию 10
_, err = file.WriteAt([]byte("Go"), 10)
if err != nil {
panic(err)
}
// Читаем содержимое
data, _ := os.ReadFile("example2.txt")
fmt.Println(string(data))
}
Результат выполнения кода:
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Go"
Как видим, первые 10 байт заполнены нулями, а затем записана строка "Go".
Смотрите также
-
интерфейс
io.ReaderAt,
который позволяет читать данные из файла по смещению -
интерфейс
io.Writer,
который записывает данные в поток последовательно -
функцию
os.WriteFile,
которая записывает данные в файл целиком -
функцию
io.WriteString,
которая упрощает запись строки в любойio.Writer