Golang io模块详细功能介绍与示例
io是 Go 语言标准库中处理 I/O 操作的核心模块,它定义了许多接口和实用函数,用于处理各种输入输出操作。下面我将详细介绍 io
模块的主要功能,并提供相应的代码示例。
1. 核心接口
1.1 io.Reader
接口
type Reader interface {
Read(p []byte) (n int, err error)
}
示例:从字符串读取数据
package main
import (
"fmt"
"io"
"strings"
)
func main() {
reader := strings.NewReader("Hello, Reader!")
buf := make([]byte, 8)
for {
n, err := reader.Read(buf)
fmt.Printf("n = %v, err = %v, buf = %v\n", n, err, buf[:n])
if err == io.EOF {
break
}
}
}
1.2 io.Writer
接口
type Writer interface {
Write(p []byte) (n int, err error)
}
示例:写入缓冲区
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Create("output.txt")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer file.Close()
n, err := io.WriteString(file, "Hello, Writer!")
if err != nil {
fmt.Println("Error writing to file:", err)
return
}
fmt.Printf("Wrote %d bytes\n", n)
}
1.3 io.Closer
接口
type Closer interface {
Close() error
}
示例:资源清理
package main
import (
"fmt"
"io"
"os"
)
func processFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close() // 确保文件被关闭
// 处理文件内容
buf := make([]byte, 1024)
for {
_, err := file.Read(buf)
if err == io.EOF {
break
}
if err != nil {
return err
}
// 处理数据...
}
return nil
}
func main() {
err := processFile("example.txt")
if err != nil {
fmt.Println("Error:", err)
}
}
1.4 io.Seeker
接口
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
}
示例:文件随机访问
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
// 移动到文件末尾
_, err = file.Seek(0, io.SeekEnd)
if err != nil {
fmt.Println("Error seeking:", err)
return
}
// 获取文件大小
size, err := file.Seek(0, io.SeekCurrent)
if err != nil {
fmt.Println("Error getting size:", err)
return
}
fmt.Printf("File size: %d bytes\n", size)
// 回到文件开头
_, err = file.Seek(0, io.SeekStart)
if err != nil {
fmt.Println("Error seeking:", err)
return
}
// 读取前10个字节
buf := make([]byte, 10)
n, err := file.Read(buf)
if err != nil {
fmt.Println("Error reading:", err)
return
}
fmt.Printf("Read %d bytes: %q\n", n, buf[:n])
}
2. 组合接口
2.1 io.ReadWriter
type ReadWriter interface {
Reader
Writer
}
2.2 io.ReadCloser
type ReadCloser interface {
Reader
Closer
}
2.3 io.WriteCloser
type WriteCloser interface {
Writer
Closer
}
2.4 io.ReadSeeker
type ReadSeeker interface {
Reader
Seeker
}
2.5 io.ReadWriteSeeker
type ReadWriteSeeker interface {
Reader
Writer
Seeker
}
示例:使用 io.ReadWriteSeeker
package main
import (
"fmt"
"io"
"strings"
)
func main() {
var rw io.ReadWriteSeeker = &strings.Builder{}
// 写入数据
_, err := rw.Write([]byte("Hello, World!"))
if err != nil {
fmt.Println("Error writing:", err)
return
}
// 回到开头
_, err = rw.Seek(0, io.SeekStart)
if err != nil {
fmt.Println("Error seeking:", err)
return
}
// 读取数据
buf := make([]byte, 5)
n, err := rw.Read(buf)
if err != nil {
fmt.Println("Error reading:", err)
return
}
fmt.Printf("Read %d bytes: %q\n", n, buf[:n])
}
3. 实用函数
3.1 io.Copy
func Copy(dst Writer, src Reader) (written int64, err error)
示例:文件复制
package main
import (
"fmt"
"io"
"os"
)
func main() {
srcFile, err := os.Open("source.txt")
if err != nil {
fmt.Println("Error opening source file:", err)
return
}
defer srcFile.Close()
dstFile, err := os.Create("destination.txt")
if err != nil {
fmt.Println("Error creating destination file:", err)
return
}
defer dstFile.Close()
bytesCopied, err := io.Copy(dstFile, srcFile)
if err != nil {
fmt.Println("Error copying file:", err)
return
}
fmt.Printf("Copied %d bytes\n", bytesCopied)
}
3.2 io.CopyN
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
示例:限制复制字节数
package main
import (
"fmt"
"io"
"strings"
)
func main() {
src := strings.NewReader("This is a long string that we will copy partially")
dst := &strings.Builder{}
bytesCopied, err := io.CopyN(dst, src, 10)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Copied %d bytes: %q\n", bytesCopied, dst.String())
}
3.3 io.ReadAll
func ReadAll(r Reader) ([]byte, error)
示例:读取所有数据
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Go is an open source programming language")
data, err := io.ReadAll(r)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Read %d bytes: %q\n", len(data), data)
}
3.4 io.ReadAtLeast
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
示例:确保读取足够数据
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello, World!")
buf := make([]byte, 10)
n, err := io.ReadAtLeast(r, buf, 5)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Read at least %d bytes: %q\n", n, buf[:n])
}
3.5 io.WriteString
func WriteString(w Writer, s string) (n int, err error)
示例:写入字符串
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Create("output.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
n, err := io.WriteString(file, "Hello, Go!")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Wrote %d bytes\n", n)
}
4. 高级功能
4.1 io.Pipe
func Pipe() (*PipeReader, *PipeWriter)
示例:管道通信
package main
import (
"fmt"
"io"
"time"
)
func main() {
r, w := io.Pipe()
// 写入协程
go func() {
defer w.Close()
for i := 0; i < 3; i++ {
fmt.Fprintf(w, "Message %d\n", i)
time.Sleep(time.Second)
}
}()
// 读取协程
go func() {
buf := make([]byte, 1024)
for {
n, err := r.Read(buf)
if err != nil {
if err == io.EOF {
fmt.Println("End of pipe")
} else {
fmt.Println("Error:", err)
}
return
}
fmt.Print("Received: ", string(buf[:n]))
}
}()
time.Sleep(4 * time.Second)
}
4.2 io.TeeReader
func TeeReader(r Reader, w Writer) Reader
示例:读取同时写入
package main
import (
"fmt"
"io"
"os"
"strings"
)
func main() {
r := strings.NewReader("Hello, TeeReader!")
var buf strings.Builder
tee := io.TeeReader(r, &buf)
// 从 tee 读取数据
data, err := io.ReadAll(tee)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Read from tee:", string(data))
fmt.Println("Written to buffer:", buf.String())
}
4.3 io.MultiReader
func MultiReader(readers ...Reader) Reader
示例:合并多个读取器
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r1 := strings.NewReader("Hello, ")
r2 := strings.NewReader("MultiReader!")
r3 := strings.NewReader(" How are you?")
multi := io.MultiReader(r1, r2, r3)
data, err := io.ReadAll(multi)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(data))
}
4.4 io.MultiWriter
func MultiWriter(writers ...Writer) Writer
示例:同时写入多个目标
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Create("output.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
multi := io.MultiWriter(os.Stdout, file)
fmt.Fprintln(multi, "This will be written to both stdout and the file")
}
5. 实用类型
5.1 io.LimitedReader
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
}
示例:限制读取字节数
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("This is a long string")
lr := &io.LimitedReader{R: r, N: 10}
buf := make([]byte, 20)
n, err := lr.Read(buf)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Read %d bytes: %q\n", n, buf[:n])
}
5.2 io.SectionReader
type SectionReader struct {
// contains filtered or unexported fields
}
示例:读取文件部分内容
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
// 创建一个 SectionReader,从第10字节开始,读取20字节
section := io.NewSectionReader(file, 10, 20)
data, err := io.ReadAll(section)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(data))
}
6. 错误处理
6.1 io.EOF
var EOF = errors.New("EOF")
示例:正确处理 EOF
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Hello")
buf := make([]byte, 10)
for {
n, err := r.Read(buf)
fmt.Printf("n = %d, err = %v\n", n, err)
if err == io.EOF {
fmt.Println("Reached end of input")
break
}
if err != nil {
fmt.Println("Error:", err)
break
}
fmt.Printf("Read %q\n", buf[:n])
}
}
6.2 io.ErrClosedPipe
var ErrClosedPipe = errors.New("io: read/write on closed pipe")
示例:处理管道关闭错误
package main
import (
"fmt"
"io"
)
func main() {
r, w := io.Pipe()
// 关闭写入端
w.Close()
_, err := w.Write([]byte("test"))
if err == io.ErrClosedPipe {
fmt.Println("Cannot write to closed pipe")
} else if err != nil {
fmt.Println("Other error:", err)
}
_, err = r.Read(make([]byte, 10))
if err == io.EOF {
fmt.Println("Read from closed pipe returns EOF")
}
}
总结
Go 语言的 io
模块提供了:
- 一组简洁而强大的接口(
Reader
,Writer
,Closer
,Seeker
等) - 多种组合接口满足不同场景需求
- 丰富的实用函数(
Copy
,ReadAll
,WriteString
等) - 高级功能如管道、多路读写等
- 完善的错误处理机制
通过合理使用这些接口和函数,可以构建高效、灵活的 I/O 处理逻辑,同时保持代码的简洁性和可维护性。