一、为什么 Reader/Writer 是 Go IO 的核心?
Go 的io包遵循 **"最小接口原则"**:仅用 1 个方法定义 "读" 和 "写",却能适配所有数据场景(文件、网络、内存等)。
io.Reader:Read(p []byte) (n int, err error)------ 从数据源读数据到pio.Writer:Write(p []byte) (n int, err error)------ 把p的数据写入目标
二、实战:自定义 Reader 读取文件片段
go
运行
Go
// 自定义Reader:读取文件的指定区间
type RangeReader struct {
file *os.File
start int64
end int64
pos int64
}
func NewRangeReader(path string, start, end int64) (*RangeReader, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
return &RangeReader{file: file, start: start, end: end, pos: start}, nil
}
// 实现Reader接口
func (r *RangeReader) Read(p []byte) (n int, err error) {
// 移动到当前读取位置
if _, err := r.file.Seek(r.pos, 0); err != nil {
return 0, err
}
// 计算本次可读取的最大长度
maxRead := r.end - r.pos + 1
if maxRead <= 0 {
return 0, io.EOF
}
if int64(len(p)) > maxRead {
p = p[:maxRead]
}
// 读取数据
n, err = r.file.Read(p)
r.pos += int64(n)
return n, err
}
三、扩展接口:Seeker/ReaderAt 的场景化使用
Seeker:调整读取偏移量(如文件随机读写)ReaderAt:从指定偏移量读取(如大文件分片读取)