Пакет io
Обзор
Пакет io предоставляет базовые интерфейсы для примитивов ввода-вывода. Его основная задача — оборачивать существующие реализации таких примитивов, например из пакета os, в общие публичные интерфейсы, абстрагирующие их функциональность, а также предоставлять некоторые другие связанные примитивы.
Поскольку эти интерфейсы и примитивы оборачивают низкоуровневые операции с различными реализациями, клиентам не следует считать их безопасными для параллельного выполнения, если не указано иное.
Указатель
Примеры
Файлы пакета
io.go multi.go pipe.go
Константы
Значения whence для Seek.
const (
SeekStart = 0 // seek relative to the origin of the file
SeekCurrent = 1 // seek relative to the current offset
SeekEnd = 2 // seek relative to the end
) Переменные
EOF — ошибка, возвращаемая Read, когда больше нет доступных входных данных. (Read должен возвращать именно EOF, а не ошибку, оборачивающую EOF, поскольку вызывающий код проверяет EOF с помощью ==.) Функции должны возвращать EOF только для обозначения штатного завершения ввода. Если EOF возникает неожиданно в структурированном потоке данных, следует вернуть ErrUnexpectedEOF или другую ошибку с более подробной информацией.
var EOF = errors.New("EOF") ErrClosedPipe — ошибка, используемая для операций чтения или записи в закрытый канал.
var ErrClosedPipe = errors.New("io: read/write on closed pipe") ErrNoProgress возвращается некоторыми клиентами Reader, когда многочисленные вызовы Read не возвращают ни данных, ни ошибки; обычно это указывает на неисправную реализацию Reader.
var ErrNoProgress = errors.New("multiple Read calls return no data or error") ErrShortBuffer означает, что для чтения требовался буфер большего размера, чем предоставленный.
var ErrShortBuffer = errors.New("short buffer") ErrShortWrite означает, что операция записи приняла меньше байтов, чем было запрошено, но не вернула явную ошибку.
var ErrShortWrite = errors.New("short write") ErrUnexpectedEOF означает, что EOF встретился в середине чтения блока фиксированного размера или структуры данных.
var ErrUnexpectedEOF = errors.New("unexpected EOF") func Copy
func Copy(dst Writer, src Reader) (written int64, err error)
Copy копирует данные из src в dst, пока в src не будет достигнут EOF или не произойдёт ошибка. Функция возвращает количество скопированных байтов и первую ошибку, возникшую при копировании, если таковая имеется.
При успешном выполнении Copy возвращает err == nil, а не err == EOF. Поскольку Copy предназначена для чтения из src до EOF, она не считает EOF, возвращённый методом Read, ошибкой, о которой следует сообщать.
Если src реализует интерфейс WriterTo, копирование выполняется вызовом src.WriteTo(dst). В противном случае, если dst реализует интерфейс ReaderFrom, копирование выполняется вызовом dst.ReadFrom(src).
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
Вывод:
some io.Reader stream to be read
func CopyBuffer 1.5
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
CopyBuffer работает так же, как Copy, за исключением того, что при необходимости использует предоставленный буфер, а не выделяет временный. Если buf равен nil, буфер выделяется; если его длина равна нулю, CopyBuffer вызывает панику.
Если src реализует интерфейс WriterTo или dst реализует интерфейс ReaderFrom, buf не будет использоваться для копирования.
Пример
Код:
r1 := strings.NewReader("first reader\n")
r2 := strings.NewReader("second reader\n")
buf := make([]byte, 8)
// buf is used here...
if _, err := io.CopyBuffer(os.Stdout, r1, buf); err != nil {
log.Fatal(err)
}
// ... reused here also. No need to allocate an extra buffer.
if _, err := io.CopyBuffer(os.Stdout, r2, buf); err != nil {
log.Fatal(err)
}
Вывод:
first reader second reader
func CopyN
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
CopyN копирует n байтов (или данные до возникновения ошибки) из src в dst. Функция возвращает количество скопированных байтов и первую ошибку, возникшую при копировании. По завершении written == n тогда и только тогда, когда err == nil.
Если dst реализует интерфейс ReaderFrom, для копирования используется этот интерфейс.
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read")
if _, err := io.CopyN(os.Stdout, r, 4); err != nil {
log.Fatal(err)
}
Вывод:
some
func Pipe
func Pipe() (*PipeReader, *PipeWriter)
Pipe создаёт синхронный канал в памяти. Его можно использовать для соединения кода, ожидающего io.Reader, с кодом, ожидающим io.Writer.
Операции чтения и записи в канале сопоставляются один к одному, кроме случаев, когда для обработки одной записи требуется несколько операций чтения. То есть каждая операция Write для PipeWriter блокируется до тех пор, пока одна или несколько операций Read для PipeReader не прочитают все записанные данные. Данные копируются непосредственно из Write в соответствующую операцию Read (или операции Read); внутренней буферизации нет.
Безопасно вызывать Read и Write параллельно друг с другом или с Close. Параллельные вызовы Read и параллельные вызовы Write также безопасны: отдельные вызовы будут последовательно проходить через блокировку.
Пример
Код:
r, w := io.Pipe()
go func() {
fmt.Fprint(w, "some io.Reader stream to be read\n")
w.Close()
}()
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
Вывод:
some io.Reader stream to be read
func ReadAll 1.16
func ReadAll(r Reader) ([]byte, error)
ReadAll читает данные из r до возникновения ошибки или достижения EOF и возвращает прочитанные данные. При успешном выполнении функция возвращает err == nil, а не err == EOF. Поскольку ReadAll предназначена для чтения из src до EOF, она не считает EOF, возвращённый методом Read, ошибкой, о которой следует сообщать.
Пример
Код:
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
b, err := io.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
Вывод:
Go is a general-purpose language designed with systems programming in mind.
func ReadAtLeast
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
ReadAtLeast читает данные из r в buf, пока не будет прочитано как минимум min байтов. Функция возвращает количество скопированных байтов и ошибку, если было прочитано меньше байтов. Ошибка будет EOF только в том случае, если не было прочитано ни одного байта. Если EOF возникает после чтения меньшего количества байтов, чем min, ReadAtLeast возвращает ErrUnexpectedEOF. Если min больше длины buf, ReadAtLeast возвращает ErrShortBuffer. По завершении n >= min тогда и только тогда, когда err == nil. Если r возвращает ошибку после чтения не менее min байтов, ошибка отбрасывается.
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
buf := make([]byte, 14)
if _, err := io.ReadAtLeast(r, buf, 4); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
// buffer smaller than minimal read size.
shortBuf := make([]byte, 3)
if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
fmt.Println("error:", err)
}
// minimal read size bigger than io.Reader stream
longBuf := make([]byte, 64)
if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
fmt.Println("error:", err)
}
Вывод:
some io.Reader error: short buffer error: unexpected EOF
func ReadFull
func ReadFull(r Reader, buf []byte) (n int, err error)
ReadFull считывает ровно len(buf) байтов из r в buf. Функция возвращает количество скопированных байтов и ошибку, если было прочитано меньше байтов. Ошибка будет EOF только в том случае, если не было прочитано ни одного байта. Если EOF возникает после чтения части, но не всех байтов, ReadFull возвращает ErrUnexpectedEOF. По завершении n == len(buf) тогда и только тогда, когда err == nil. Если r возвращает ошибку после чтения не менее len(buf) байтов, ошибка отбрасывается.
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
buf := make([]byte, 4)
if _, err := io.ReadFull(r, buf); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
// minimal read size bigger than io.Reader stream
longBuf := make([]byte, 64)
if _, err := io.ReadFull(r, longBuf); err != nil {
fmt.Println("error:", err)
}
Вывод:
some error: unexpected EOF
func WriteString
func WriteString(w Writer, s string) (n int, err error)
WriteString записывает содержимое строки s в w, принимающий срез байтов. Если w реализует интерфейс StringWriter, напрямую вызывается StringWriter.WriteString. В противном случае ровно один раз вызывается Writer.Write.
Пример
Код:
if _, err := io.WriteString(os.Stdout, "Hello World"); err != nil {
log.Fatal(err)
}
Вывод:
Hello World
type ByteReader
ByteReader — это интерфейс, предоставляющий метод ReadByte.
ReadByte считывает и возвращает следующий байт из входных данных или возникшую ошибку. Если ReadByte возвращает ошибку, входной байт не был потреблён, а возвращённое значение байта не определено.
ReadByte предоставляет эффективный интерфейс для обработки данных побайтно. К Reader, не реализующему ByteReader, можно добавить этот метод с помощью обёртки bufio.NewReader.
type ByteReader interface {
ReadByte() (byte, error)
} type ByteScanner
ByteScanner — это интерфейс, который дополняет базовый метод ReadByte методом UnreadByte.
UnreadByte заставляет следующий вызов ReadByte вернуть последний прочитанный байт. Если последняя операция не была успешным вызовом ReadByte, UnreadByte может вернуть ошибку, отменить чтение последнего прочитанного байта (или байта перед последним отменённым чтением) либо (в реализациях, поддерживающих интерфейс Seeker) переместиться на один байт назад относительно текущего смещения.
type ByteScanner interface {
ByteReader
UnreadByte() error
} type ByteWriter 1.1
ByteWriter — это интерфейс, предоставляющий метод WriteByte.
type ByteWriter interface {
WriteByte(c byte) error
} type Closer
Closer — это интерфейс, предоставляющий базовый метод Close.
Поведение Close при повторных вызовах не определено. Конкретные реализации могут документировать собственное поведение.
type Closer interface {
Close() error
} type LimitedReader
LimitedReader читает данные из R, ограничивая объём возвращаемых данных значением N байтов. Каждый вызов Read обновляет N, отражая оставшееся количество байтов. Read возвращает EOF, если N <= 0 или если базовый R возвращает EOF.
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
}
func (*LimitedReader) Read
func (l *LimitedReader) Read(p []byte) (n int, err error)
type OffsetWriter 1.20
OffsetWriter преобразует смещение записи base в смещение base+off в базовом объекте записи.
type OffsetWriter struct {
// contains filtered or unexported fields
}
func NewOffsetWriter 1.20
func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter
NewOffsetWriter возвращает OffsetWriter, который выполняет запись в w, начиная со смещения off.
func (*OffsetWriter) Seek 1.20
func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error)
func (*OffsetWriter) Write 1.20
func (o *OffsetWriter) Write(p []byte) (n int, err error)
func (*OffsetWriter) WriteAt 1.20
func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error)
type PipeReader
PipeReader — это читающая часть канала.
type PipeReader struct {
// contains filtered or unexported fields
}
func (*PipeReader) Close
func (r *PipeReader) Close() error
Close закрывает средство чтения; последующие записи в записывающую часть канала будут возвращать ошибку ErrClosedPipe.
func (*PipeReader) CloseWithError
func (r *PipeReader) CloseWithError(err error) error
CloseWithError закрывает средство чтения; последующие записи в записывающую часть канала будут возвращать ошибку err.
CloseWithError не перезаписывает предыдущую ошибку, если она существует, и всегда возвращает nil.
func (*PipeReader) Read
func (r *PipeReader) Read(data []byte) (n int, err error)
Read реализует стандартный интерфейс Read: он считывает данные из канала, блокируя выполнение до появления записывающей стороны или закрытия записывающего конца. Если записывающий конец закрыт с ошибкой, эта ошибка возвращается как err; в противном случае err равен EOF.
type PipeWriter
PipeWriter — это записывающая часть канала.
type PipeWriter struct {
// contains filtered or unexported fields
}
func (*PipeWriter) Close
func (w *PipeWriter) Close() error
Close закрывает средство записи; последующие чтения из читающей части канала не будут возвращать байты и вернут EOF.
func (*PipeWriter) CloseWithError
func (w *PipeWriter) CloseWithError(err error) error
CloseWithError закрывает средство записи; последующие чтения из читающей части канала не будут возвращать байты и вернут ошибку err либо EOF, если err равен nil.
CloseWithError не перезаписывает предыдущую ошибку, если она существует, и всегда возвращает nil.
func (*PipeWriter) Write
func (w *PipeWriter) Write(data []byte) (n int, err error)
Write реализует стандартный интерфейс Write: он записывает данные в канал, блокируя выполнение до тех пор, пока один или несколько читателей не получат все данные или не будет закрыт читающий конец. Если читающий конец закрыт с ошибкой, эта ошибка возвращается как err; в противном случае err равен ErrClosedPipe.
type ReadCloser
ReadCloser — это интерфейс, объединяющий базовые методы Read и Close.
type ReadCloser interface {
Reader
Closer
} func NopCloser 1.16
func NopCloser(r Reader) ReadCloser
NopCloser возвращает ReadCloser с пустым методом Close, оборачивающий предоставленный Reader r. Если r реализует WriterTo, возвращаемый ReadCloser будет реализовывать WriterTo, перенаправляя вызовы к r.
type ReadSeekCloser 1.16
ReadSeekCloser — это интерфейс, объединяющий базовые методы Read, Seek и Close.
type ReadSeekCloser interface {
Reader
Seeker
Closer
} type ReadSeeker
ReadSeeker — это интерфейс, объединяющий базовые методы Read и Seek.
type ReadSeeker interface {
Reader
Seeker
} type ReadWriteCloser
ReadWriteCloser — это интерфейс, объединяющий базовые методы Read, Write и Close.
type ReadWriteCloser interface {
Reader
Writer
Closer
} type ReadWriteSeeker
ReadWriteSeeker — это интерфейс, объединяющий базовые методы Read, Write и Seek.
type ReadWriteSeeker interface {
Reader
Writer
Seeker
} type ReadWriter
ReadWriter — это интерфейс, объединяющий базовые методы Read и Write.
type ReadWriter interface {
Reader
Writer
} type Reader
Reader — это интерфейс, который оборачивает базовый метод Read.
Read считывает до len(p) байт в p. Он возвращает количество прочитанных байт (0 <= n <= len(p)) и любую возникшую ошибку. Даже если Read возвращает n < len(p), во время вызова он может использовать весь p как рабочее пространство. Если данные доступны, но их меньше, чем len(p) байт, Read обычно возвращает доступные данные, не дожидаясь остальных.
Если после успешного чтения n > 0 байт Read обнаруживает ошибку или конец файла, он возвращает количество прочитанных байт. Он может вернуть ненулевую ошибку в том же вызове или вернуть ошибку (и n == 0) при последующем вызове. Пример такого общего случая: Reader, возвращающий ненулевое количество байт в конце входного потока, может вернуть как err == EOF, так и err == nil. Следующий вызов Read должен вернуть 0, EOF.
Вызывающий код должен всегда обрабатывать возвращённые n > 0 байт, прежде чем учитывать ошибку err. Это позволяет корректно обрабатывать ошибки ввода-вывода, возникающие после чтения некоторого количества байт, а также оба допустимых варианта поведения при EOF.
Если len(p) == 0, Read всегда должен возвращать n == 0. Он может вернуть ненулевую ошибку, если известно о наличии ошибки, например EOF.
Реализациям Read не рекомендуется возвращать нулевое количество байт без ошибки, кроме случая len(p) == 0. Вызывающий код должен трактовать возвращаемые 0 и nil как признак того, что ничего не произошло; в частности, это не означает EOF.
Реализации не должны сохранять p.
type Reader interface {
Read(p []byte) (n int, err error)
} func LimitReader
func LimitReader(r Reader, n int64) Reader
LimitReader возвращает Reader, который считывает данные из r, но останавливается с EOF после n байт. Базовая реализация — *LimitedReader.
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
lr := io.LimitReader(r, 4)
if _, err := io.Copy(os.Stdout, lr); err != nil {
log.Fatal(err)
}
Вывод:
some
func MultiReader
func MultiReader(readers ...Reader) Reader
MultiReader возвращает Reader, представляющий собой логическое объединение предоставленных входных средств чтения. Они считываются последовательно. Когда все входные данные вернут EOF, Read вернёт EOF. Если какое-либо из средств чтения вернёт ненулевую ошибку, отличную от EOF, Read вернёт эту ошибку.
Пример
Код:
r1 := strings.NewReader("first reader ")
r2 := strings.NewReader("second reader ")
r3 := strings.NewReader("third reader\n")
r := io.MultiReader(r1, r2, r3)
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
Вывод:
first reader second reader third reader
func TeeReader
func TeeReader(r Reader, w Writer) Reader
TeeReader возвращает Reader, который записывает в w то, что считывает из r. Каждому чтению из r через него соответствует запись в w. Внутренняя буферизация отсутствует — запись должна завершиться до завершения чтения. Любая ошибка, возникшая при записи, сообщается как ошибка чтения.
Пример
Код:
var r io.Reader = strings.NewReader("some io.Reader stream to be read\n")
r = io.TeeReader(r, os.Stdout)
// Everything read from r will be copied to stdout.
if _, err := io.ReadAll(r); err != nil {
log.Fatal(err)
}
Вывод:
some io.Reader stream to be read
type ReaderAt
ReaderAt — это интерфейс, который оборачивает базовый метод ReadAt.
ReadAt считывает len(p) байт в p, начиная со смещения off в базовом источнике ввода. Он возвращает количество прочитанных байт (0 <= n <= len(p)) и любую возникшую ошибку.
Если ReadAt возвращает n < len(p), он возвращает ненулевую ошибку, объясняющую, почему не были возвращены дополнительные байты. В этом отношении ReadAt строже, чем Read.
Даже если ReadAt возвращает n < len(p), во время вызова он может использовать весь p как рабочее пространство. Если данные доступны, но их меньше, чем len(p) байт, ReadAt блокируется до тех пор, пока не станут доступны все данные или не возникнет ошибка. В этом отношении ReadAt отличается от Read.
Если n = len(p) байт, возвращённых ReadAt, находятся в конце источника ввода, ReadAt может вернуть как err == EOF, так и err == nil.
Если ReadAt читает из источника ввода со смещением поиска, ReadAt не должен влиять на базовое смещение поиска и не должен зависеть от него.
Клиенты ReadAt могут выполнять параллельные вызовы ReadAt для одного и того же источника ввода.
Реализации не должны сохранять p.
type ReaderAt interface {
ReadAt(p []byte, off int64) (n int, err error)
} type ReaderFrom
ReaderFrom — это интерфейс, который оборачивает метод ReadFrom.
ReadFrom читает данные из r до EOF или ошибки. Возвращаемое значение n — количество прочитанных байтов. Также возвращается любая ошибка, кроме EOF, возникшая во время чтения.
Функция Copy использует ReaderFrom, если он доступен.
type ReaderFrom interface {
ReadFrom(r Reader) (n int64, err error)
} type RuneReader
RuneReader — это интерфейс, который оборачивает метод ReadRune.
ReadRune читает один закодированный символ Unicode и возвращает руну и её размер в байтах. Если символ недоступен, задаётся err.
type RuneReader interface {
ReadRune() (r rune, size int, err error)
} type RuneScanner
RuneScanner — это интерфейс, который добавляет метод UnreadRune к базовому методу ReadRune.
UnreadRune приводит к тому, что следующий вызов ReadRune возвращает последнюю прочитанную руну. Если последняя операция не была успешным вызовом ReadRune, UnreadRune может вернуть ошибку, отменить чтение последней прочитанной руны (или руны перед последней отменённой) либо (в реализациях, поддерживающих интерфейс Seeker) перейти к началу руны перед текущим смещением.
type RuneScanner interface {
RuneReader
UnreadRune() error
} type SectionReader
SectionReader реализует Read, Seek и ReadAt для участка базового ReaderAt.
type SectionReader struct {
// contains filtered or unexported fields
}
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
if _, err := io.Copy(os.Stdout, s); err != nil {
log.Fatal(err)
}
Вывод:
io.Reader stream
func NewSectionReader
func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
NewSectionReader возвращает SectionReader, который читает данные из r, начиная со смещения off, и останавливается с EOF после чтения n байтов.
func (*SectionReader) Outer 1.22
func (s *SectionReader) Outer() (r ReaderAt, off int64, n int64)
Outer возвращает базовый ReaderAt и смещения участка.
Возвращённые значения совпадают со значениями, переданными в NewSectionReader при создании SectionReader.
func (*SectionReader) Read
func (s *SectionReader) Read(p []byte) (n int, err error)
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
buf := make([]byte, 9)
if _, err := s.Read(buf); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
Вывод:
io.Reader
func (*SectionReader) ReadAt
func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
buf := make([]byte, 6)
if _, err := s.ReadAt(buf, 10); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
Вывод:
stream
func (*SectionReader) Seek
func (s *SectionReader) Seek(offset int64, whence int) (int64, error)
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
if _, err := s.Seek(10, io.SeekStart); err != nil {
log.Fatal(err)
}
if _, err := io.Copy(os.Stdout, s); err != nil {
log.Fatal(err)
}
Вывод:
stream
func (*SectionReader) Size
func (s *SectionReader) Size() int64
Size возвращает размер участка в байтах.
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
fmt.Println(s.Size())
Вывод:
17
type Seeker
Seeker — это интерфейс, который оборачивает базовый метод Seek.
Seek задаёт смещение для следующего Read или Write относительно offset, интерпретируя whence следующим образом: SeekStart означает отсчёт от начала файла, SeekCurrent — от текущего смещения, а SeekEnd — от конца (например, offset = -2 указывает на предпоследний байт файла). Seek возвращает новое смещение относительно начала файла или ошибку, если она возникла.
Попытка перейти к смещению перед началом файла приводит к ошибке. Переход к любому положительному смещению может быть разрешён, однако, если новое смещение превышает размер базового объекта, поведение последующих операций ввода-вывода зависит от реализации.
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
} type StringWriter 1.12
StringWriter — это интерфейс, который оборачивает метод WriteString.
type StringWriter interface {
WriteString(s string) (n int, err error)
} type WriteCloser
WriteCloser — это интерфейс, объединяющий базовые методы Write и Close.
type WriteCloser interface {
Writer
Closer
} type WriteSeeker
WriteSeeker — это интерфейс, объединяющий базовые методы Write и Seek.
type WriteSeeker interface {
Writer
Seeker
} type Writer
Writer — это интерфейс, который оборачивает базовый метод Write.
Write записывает len(p) байтов из p в базовый поток данных. Он возвращает количество записанных байтов из p (0 <= n <= len(p)) и любую ошибку, из-за которой запись завершилась раньше времени. Если Write возвращает n < len(p), он должен вернуть ненулевую ошибку. Write не должен изменять данные среза, даже временно.
Реализации не должны сохранять p.
type Writer interface {
Write(p []byte) (n int, err error)
} Discard — это Writer, у которого все вызовы Write завершаются успешно и ничего не делают.
var Discard Writer = discard{} func MultiWriter
func MultiWriter(writers ...Writer) Writer
MultiWriter создаёт writer, который дублирует записи во все переданные writer, подобно команде Unix tee(1).
Каждая запись последовательно записывается в каждый writer из списка. Если какой-либо writer из списка возвращает ошибку, операция записи прекращается и возвращает эту ошибку; запись в остальные writer не продолжается.
Пример
Код:
r := strings.NewReader("some io.Reader stream to be read\n")
var buf1, buf2 strings.Builder
w := io.MultiWriter(&buf1, &buf2)
if _, err := io.Copy(w, r); err != nil {
log.Fatal(err)
}
fmt.Print(buf1.String())
fmt.Print(buf2.String())
Вывод:
some io.Reader stream to be read some io.Reader stream to be read
type WriterAt
WriterAt — это интерфейс, который оборачивает базовый метод WriteAt.
WriteAt записывает len(p) байтов из p в базовый поток данных, начиная со смещения off. Он возвращает количество записанных байтов из p (0 <= n <= len(p)) и любую ошибку, из-за которой запись завершилась раньше времени. Если WriteAt возвращает n < len(p), он должен вернуть ненулевую ошибку.
Если WriteAt записывает данные в назначение со смещением поиска, WriteAt не должен влиять на базовое смещение поиска и не должен зависеть от него.
Клиенты WriteAt могут выполнять параллельные вызовы WriteAt для одного и того же назначения, если диапазоны не пересекаются.
Реализации не должны сохранять p.
type WriterAt interface {
WriteAt(p []byte, off int64) (n int, err error)
} type WriterTo
WriterTo — это интерфейс, который оборачивает метод WriteTo.
WriteTo записывает данные в w, пока данные не закончатся или не произойдёт ошибка. Возвращаемое значение n — количество записанных байтов. Также возвращается любая ошибка, возникшая во время записи.
Функция Copy использует WriterTo, если он доступен.
type WriterTo interface {
WriteTo(w Writer) (n int64, err error)
} Подкаталоги
| Имя | Краткое описание |
|---|---|
| .. | |
| fs | Пакет fs определяет базовые интерфейсы файловой системы. |
| ioutil | Пакет ioutil реализует несколько вспомогательных функций ввода-вывода. |
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/io/