package io
import "io"
io 包提供I/O原语的基础接口。 其主要作用是将此类原语的现有实现(如os包中的实现) 封装为抽象功能的共享公共接口,并附带一些其他相关原语。
由于这些接口和原语封装了具有不同实现的底层操作, 除非另有说明,调用方不应假定它们可安全用于并行执行。
Index
- Constants
- Variables
- func Copy(dst Writer, src Reader) (written int64, err error)
- func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
- func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
- func Pipe() (*PipeReader, *PipeWriter)
- func ReadAll(r Reader) ([]byte, error)
- func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
- func ReadFull(r Reader, buf []byte) (n int, err error)
- func WriteString(w Writer, s string) (n int, err error)
- type ByteReader
- type ByteScanner
- type ByteWriter
- type Closer
- type LimitedReader
- type OffsetWriter
- type PipeReader
- type PipeWriter
- type ReadCloser
- type ReadSeekCloser
- type ReadSeeker
- type ReadWriteCloser
- type ReadWriteSeeker
- type ReadWriter
- type Reader
- type ReaderAt
- type ReaderFrom
- type RuneReader
- type RuneScanner
-
type SectionReader
- func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
- func (s *SectionReader) Outer() (r ReaderAt, off int64, n int64)
- func (s *SectionReader) Read(p []byte) (n int, err error)
- func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)
- func (s *SectionReader) Seek(offset int64, whence int) (int64, error)
- func (s *SectionReader) Size() int64
- type Seeker
- type StringWriter
- type WriteCloser
- type WriteSeeker
- type Writer
- type WriterAt
- type WriterTo
Examples
- Copy
- CopyBuffer
- CopyN
- LimitReader
- MultiReader
- MultiWriter
- Pipe
- ReadAll
- ReadAtLeast
- ReadFull
- SectionReader
- SectionReader.Read
- SectionReader.ReadAt
- SectionReader.Seek
- SectionReader.Size
- TeeReader
- WriteString
Constants
const ( SeekStart = 0 // 相对于文件起始位置进行偏移 SeekCurrent = 1 // 相对于当前偏移位置进行偏移 SeekEnd = 2 // 相对于文件末尾进行偏移 )
Seek 起始基准值。
Variables
var EOF = errors.New("EOF")
EOF 是Read方法在无更多输入数据时返回的错误。 (Read必须直接返回EOF本身,而非包装EOF的错误, 因为调用方会通过==判断EOF。) 函数仅应在输入正常结束时返回EOF。 若在结构化数据流中意外遇到EOF, 应返回[ErrUnexpectedEOF]或其他能提供更多细节的错误。
var ErrClosedPipe = errors.New("io: read/write on closed pipe")
ErrClosedPipe 是对已关闭管道执行读或写操作时返回的错误。
var ErrNoProgress = errors.New("multiple Read calls return no data or error")
ErrNoProgress 由部分[Reader]调用方返回, 当多次调用Read均未返回任何数据或错误时触发, 通常表明[Reader]的实现存在问题。
var ErrShortBuffer = errors.New("short buffer")
ErrShortBuffer 表示读取操作需要的缓冲区长度大于提供的长度。
var ErrShortWrite = errors.New("short write")
ErrShortWrite 表示写入操作接收的字节数少于请求数量, 但未返回显式错误。
var ErrUnexpectedEOF = errors.New("unexpected EOF")
ErrUnexpectedEOF 表示在读取固定大小的数据块或数据结构的过程中 遇到了EOF。
Functions
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, 因此不会将Read返回的EOF视为需要上报的错误。
若src实现[WriterTo],
则通过调用src.WriteTo(dst)实现复制。
否则,若dst实现[ReaderFrom],
则通过调用dst.ReadFrom(src)实现复制。
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
CopyBuffer 与Copy功能相同,区别在于它通过提供的缓冲区(若需要) 中转数据,而非分配临时缓冲区。若buf为nil,则自动分配缓冲区; 若buf长度为0,CopyBuffer会触发panic。
若src实现[WriterTo]或dst实现[ReaderFrom],
则不会使用buf执行复制。
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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 从src向dst复制n个字节(或直至发生错误)。 它返回复制的字节数,以及复制过程中遇到的首个错误。 返回时,当且仅当err == nil时,written == n。
若dst实现[ReaderFrom],则通过该接口实现复制。
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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 的代码连接起来。
管道上的读操作与写操作一一对应,除非需要多次读操作才能消费完一次写入的数据。 也就是说,对 PipeWriter 的每次写入都会阻塞,直到 PipeReader 的一次或多次读操作 完全消费完写入的数据。 数据从写入操作直接复制到对应的读操作(或多次读操作)中,无内部缓冲。
并行调用 Read、Write 或 Close 是安全的。
并行调用多次 Read、并行调用多次 Write 同样安全:
各个调用会被串行化执行。
Output:Example
package main
import (
"fmt"
"io"
"log"
"os"
)
func main() {
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
func ReadAll(r Reader) ([]byte, error)
ReadAll 从r中读取数据直至发生错误或EOF,
并返回读取到的数据。
成功调用会返回err == nil,而非err == EOF。
由于ReadAll的定义是从源读取至EOF,
因此不会将Read返回的EOF视为需要上报的错误。
Output:Example
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
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。
若在读取不足min个字节后遇到EOF,
ReadAtLeast返回[ErrUnexpectedEOF]。
若min大于buf的长度,ReadAtLeast返回[ErrShortBuffer]。
返回时,当且仅当err == nil时,n >= min。
若r在至少读取min个字节后返回错误,该错误会被忽略。
Output:Example
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
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 从r中精确读取len(buf)个字节至buf。
它返回复制的字节数,若读取字节数不足则返回错误。
仅当未读取任何字节时,错误才为EOF。
若在读取部分但非全部字节后遇到EOF,
ReadFull返回[ErrUnexpectedEOF]。
返回时,当且仅当err == nil时,n == len(buf)。
若r在至少读取len(buf)个字节后返回错误,该错误会被忽略。
Output:Example
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
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为接收字节切片的写入器。
若w实现[StringWriter],则直接调用[StringWriter.WriteString]。
否则,仅调用一次[Writer.Write]。
Output:Example
package main
import (
"io"
"log"
"os"
)
func main() {
if _, err := io.WriteString(os.Stdout, "Hello World"); err != nil {
log.Fatal(err)
}
}
Hello World
Types
type ByteReader
type ByteReader interface { ReadByte() (byte, error) }
ByteReader 是封装ReadByte方法的接口。
ReadByte 从输入中读取并返回下一个字节, 或返回遇到的任何错误。若ReadByte返回错误, 则未消耗任何输入字节,返回的字节值未定义。
ReadByte 为逐字节处理提供了高效接口。 未实现ByteReader的[Reader]可通过bufio.NewReader包装 以添加该方法。
type ByteScanner
type ByteScanner interface { ByteReader UnreadByte() error }
ByteScanner 是在基础ReadByte方法基础上 新增UnreadByte方法的接口。
UnreadByte 会使下一次ReadByte调用返回最后读取的字节。 若上一次操作并非成功的ReadByte调用,UnreadByte可能 返回错误、回退最后读取的字节(或上一次回退字节的前一个字节), 或(在支持[Seeker]接口的实现中)将偏移量定位至当前位置的前一个字节。
type ByteWriter
type ByteWriter interface { WriteByte(c byte) error }
ByteWriter 是封装WriteByte方法的接口。
type Closer
type Closer interface { Close() error }
Closer 是封装基础Close方法的接口。
首次调用Close后的行为未定义。 具体实现可自行文档化其行为。
type LimitedReader
type LimitedReader struct { R Reader // 底层读取器 N int64 // 剩余最大可读字节数 }
LimitedReader 从R中读取数据,但将返回的数据量限制为N个字节。 每次调用Read都会更新N以反映剩余的可读数据量。 当N <= 0或底层R返回EOF时,Read返回EOF。
func (*LimitedReader) Read
func (l *LimitedReader) Read(p []byte) (n int, err error)
type OffsetWriter
type OffsetWriter struct { // contains filtered or unexported fields }
OffsetWriter 将在base偏移量处的写入操作, 映射到底层写入器的base+off偏移量处。
func NewOffsetWriter
func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter
NewOffsetWriter 返回一个[OffsetWriter], 该写入器从off偏移位置开始向w中写入数据。
func (*OffsetWriter) Seek
func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error)
func (*OffsetWriter) Write
func (o *OffsetWriter) Write(p []byte) (n int, err error)
func (*OffsetWriter) WriteAt
func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error)
type PipeReader
type PipeReader struct { // contains filtered or unexported fields }
PipeReader 是管道的读取端。
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
type PipeWriter struct { // contains filtered or unexported fields }
PipeWriter 是管道的写入端。
func (*PipeWriter) Close
func (w *PipeWriter) Close() error
Close 关闭写入端;后续从管道读取端的读取操作将返回0字节数据及EOF。
func (*PipeWriter) CloseWithError
func (w *PipeWriter) CloseWithError(err error) error
CloseWithError 关闭写入端;后续从管道读取端的读取操作将返回0字节数据及err错误, 若err为nil则返回EOF。
若已存在错误,CloseWithError 不会覆盖原有错误,且始终返回 nil。
func (*PipeWriter) Write
func (w *PipeWriter) Write(data []byte) (n int, err error)
Write 实现标准的 Write 接口: 它向管道写入数据,会阻塞直到一个或多个读取方消费完所有数据,或读取端关闭。 若读取端因错误关闭,该错误会作为 err 返回;否则 err 为 ErrClosedPipe。
type ReadCloser
type ReadCloser interface { Reader Closer }
ReadCloser 是组合基础Read和Close方法的接口。
func NopCloser
func NopCloser(r Reader) ReadCloser
NopCloser 返回一个包装了提供的[Reader] r的[ReadCloser], 其Close方法为空操作。 若r实现[WriterTo],返回的[ReadCloser]会通过转发调用至r 来实现[WriterTo]接口。
type ReadSeekCloser
type ReadSeekCloser interface { Reader Seeker Closer }
ReadSeekCloser 是组合基础Read、Seek和Close方法的接口。
type ReadSeeker
type ReadSeeker interface { Reader Seeker }
ReadSeeker 是组合基础Read和Seek方法的接口。
type ReadWriteCloser
type ReadWriteCloser interface { Reader Writer Closer }
ReadWriteCloser 是组合基础Read、Write和Close方法的接口。
type ReadWriteSeeker
type ReadWriteSeeker interface { Reader Writer Seeker }
ReadWriteSeeker 是组合基础Read、Write和Seek方法的接口。
type ReadWriter
type ReadWriter interface { Reader Writer }
ReadWriter 是组合基础Read和Write方法的接口。
type Reader
type Reader interface { Read(p []byte) (n int, err error) }
Reader 是封装基础Read方法的接口。
Read 最多将len(p)个字节读入p中。它返回读取的字节数 (0 <= n <= len(p))以及遇到的任何错误。即使Read返回 n < len(p),调用过程中也可能将整个p用作临时空间。 若存在部分可用数据但不足len(p)个字节,Read通常会 返回当前可用数据,而非等待更多数据。
当Read在成功读取n > 0个字节后遇到错误或文件结束条件时, 会返回已读取的字节数。它可在本次调用中返回(非nil)错误, 或在后续调用中返回错误(且n == 0)。 此类常见场景的一个例子是:在输入流末尾返回非零字节数的Reader, 可能返回err == EOF或err == nil。下一次Read应返回0, EOF。
调用方应始终先处理返回的n > 0个字节,再考虑错误err。 这样能正确处理读取部分字节后发生的I/O错误, 以及两种允许的EOF行为。
若len(p) == 0,Read应始终返回n == 0。若已知存在错误条件(如EOF), 可返回非nil错误。
不鼓励Read的实现返回零字节计数且nil错误,len(p) == 0的情况除外。 调用方应将返回0和nil视为无任何操作发生; 尤其该情况不表示EOF。
实现不得持有p的引用。
func LimitReader
func LimitReader(r Reader, n int64) Reader
LimitReader 返回一个Reader,该读取器从r中读取数据,
但在读取n个字节后以EOF终止。
底层实现为*LimitedReader。
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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 返回一个读取器,该读取器是所提供输入读取器的逻辑拼接
会按顺序读取这些输入读取器。一旦所有输入都返回 EOF,Read 方法将返回 EOF
若任意一个读取器返回非空、非 EOF 的错误,Read 方法将返回该错误
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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],该读取器会将从r中读取的内容
同时写入w。
通过该读取器从r执行的所有读取操作,
都会对应执行向w的写入操作。无内部缓冲——
写入必须在读取完成前执行完毕。
写入过程中遇到的任何错误都会作为读取错误上报。
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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
type ReaderAt interface { ReadAt(p []byte, off int64) (n int, err error) }
ReaderAt 是封装基础ReadAt方法的接口。
ReadAt 从底层输入源的off偏移位置开始, 将len(p)个字节读入p中。它返回读取的字节数 (0 <= n <= len(p))以及遇到的任何错误。
当ReadAt返回n < len(p)时,会返回非nil错误以解释 未返回更多字节的原因。在这一点上,ReadAt比Read更严格。
即使ReadAt返回n < len(p),调用过程中也可能将整个p用作临时空间。 若存在部分可用数据但不足len(p)个字节,ReadAt会阻塞 直至所有数据可用或发生错误。在这一点上,ReadAt与Read不同。
若ReadAt返回的n = len(p)个字节位于输入源末尾, ReadAt可返回err == EOF或err == nil。
若ReadAt从带有偏移量的输入源读取, ReadAt不应影响底层偏移量,也不受其影响。
ReadAt的调用方可对同一输入源并行执行多个ReadAt调用。
实现不得持有p的引用。
type ReaderFrom
type ReaderFrom interface { ReadFrom(r Reader) (n int64, err error) }
ReaderFrom 是封装ReadFrom方法的接口。
ReadFrom 从r中读取数据直至EOF或发生错误。 返回值n为读取的字节数。 读取过程中遇到的除EOF外的任何错误也会一并返回。
若可用,[Copy]函数会使用[ReaderFrom]。
type RuneReader
type RuneReader interface { ReadRune() (r rune, size int, err error) }
RuneReader 是封装ReadRune方法的接口。
ReadRune 读取单个编码的Unicode字符, 并返回该符文及其字节长度。若无可用字符,会设置err。
type RuneScanner
type RuneScanner interface { RuneReader UnreadRune() error }
RuneScanner 是在基础ReadRune方法基础上 新增UnreadRune方法的接口。
UnreadRune 会使下一次ReadRune调用返回最后读取的符文。 若上一次操作并非成功的ReadRune调用,UnreadRune可能 返回错误、回退最后读取的符文(或上一次回退符文的前一个符文), 或(在支持[Seeker]接口的实现中)将偏移量定位至当前符文的起始位置。
type SectionReader
type SectionReader struct { // contains filtered or unexported fields }
SectionReader 在底层[ReaderAt]的指定片段上
实现Read、Seek和ReadAt方法。
Output:Example
package main
import (
"io"
"log"
"os"
"strings"
)
func main() {
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偏移位置开始读取, 读取n个字节后以EOF终止。
func (*SectionReader) Outer
func (s *SectionReader) Outer() (r ReaderAt, off int64, n int64)
Outer 返回该片段对应的底层[ReaderAt]与偏移量。
返回值与创建[SectionReader]时 传入[NewSectionReader]的参数一致。
func (*SectionReader) Read
func (s *SectionReader) Read(p []byte) (n int, err error)
Example
package main import ( "fmt" "io" "log" "strings" ) func main() { 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) }
Output:
io.Reader
func (*SectionReader) ReadAt
func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)
Example
package main import ( "fmt" "io" "log" "strings" ) func main() { 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) }
Output:
stream
func (*SectionReader) Seek
func (s *SectionReader) Seek(offset int64, whence int) (int64, error)
Example
package main import ( "io" "log" "os" "strings" ) func main() { 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) } }
Output:
stream
func (*SectionReader) Size
func (s *SectionReader) Size() int64
Size 返回该片段的字节大小。
Output:Example
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
fmt.Println(s.Size())
}
17
type Seeker
type Seeker interface { Seek(offset int64, whence int) (int64, error) }
Seeker 是封装基础Seek方法的接口。
Seek 将下一次Read或Write的偏移量设置为offset, 偏移规则由whence指定: SeekStart 表示相对于文件起始位置, SeekCurrent 表示相对于当前偏移位置, SeekEnd 表示相对于文件末尾 (例如,offset = -2 指定文件的倒数第二个字节)。 Seek 返回相对于文件起始位置的新偏移量,或发生的错误。
偏移至文件起始位置之前属于错误操作。 允许偏移至任意正偏移量,但若新偏移量超过 底层对象的大小,后续I/O操作的行为由具体实现决定。
type StringWriter
type StringWriter interface { WriteString(s string) (n int, err error) }
StringWriter 是封装WriteString方法的接口。
type WriteCloser
type WriteCloser interface { Writer Closer }
WriteCloser 是组合基础Write和Close方法的接口。
type WriteSeeker
type WriteSeeker interface { Writer Seeker }
WriteSeeker 是组合基础Write和Seek方法的接口。
type Writer
type Writer interface { Write(p []byte) (n int, err error) }
Writer 是封装基础Write方法的接口。
Write 从p中将len(p)个字节写入底层数据流。 它返回从p中写入的字节数(0 <= n <= len(p)) 以及导致写入提前终止的任何错误。 若Write返回n < len(p),则必须返回非nil错误。 Write不得修改切片数据,即使是临时修改也不允许。
实现不得持有p的引用。
var Discard Writer = discard{}
Discard 是一个[Writer],所有对其的Write调用 均会成功执行且不做任何实际操作。
func MultiWriter
func MultiWriter(writers ...Writer) Writer
MultiWriter 创建一个写入器,该写入器会将写入操作复制到所有提供的写入器 类似于 Unix 的 tee(1) 命令
每次写入会依次写入列表中的每个写入器
若列表中的某个写入器返回错误,整个写入操作将停止并返回该错误
不会继续向后续写入器执行写入
Output:Example
package main
import (
"fmt"
"io"
"log"
"strings"
)
func main() {
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
type WriterAt interface { WriteAt(p []byte, off int64) (n int, err error) }
WriterAt 是封装基础WriteAt方法的接口。
WriteAt 从p中将len(p)个字节写入底层数据流的off偏移位置。 它返回从p中写入的字节数(0 <= n <= len(p)) 以及导致写入提前终止的任何错误。 若WriteAt返回n < len(p),则必须返回非nil错误。
若WriteAt向带有偏移量的目标写入, WriteAt不应影响底层偏移量,也不受其影响。
若写入范围不重叠,WriteAt的调用方可对同一目标 并行执行多个WriteAt调用。
实现不得持有p的引用。
type WriterTo
type WriterTo interface { WriteTo(w Writer) (n int64, err error) }
WriterTo 是封装WriteTo方法的接口。
WriteTo 向w中写入数据,直至无更多数据可写或发生错误。 返回值n为写入的字节数。 写入过程中遇到的任何错误也会一并返回。
若可用,Copy函数会使用WriterTo。
Directories
| fs | fs 包定义了文件系统的基础接口。 |
| ioutil | ioutil 包实现了一些 I/O 工具函数。 |