当前位置: 首页 > article >正文

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 模块提供了:

  1. 一组简洁而强大的接口(Reader, Writer, Closer, Seeker 等)
  2. 多种组合接口满足不同场景需求
  3. 丰富的实用函数(Copy, ReadAll, WriteString 等)
  4. 高级功能如管道、多路读写等
  5. 完善的错误处理机制

通过合理使用这些接口和函数,可以构建高效、灵活的 I/O 处理逻辑,同时保持代码的简洁性和可维护性。


http://www.kler.cn/a/611687.html

相关文章:

  • 数据大屏点亮工业互联网的智慧之眼
  • linux网络编程以及epoll IO多路复用
  • 计算机网络基础:量子通信技术在网络中的应用前景
  • 解决Cubemx生产的 .ioc文件不能外部打开的方法
  • Vulhub靶机--FAll
  • 数据湖的崛起:从大数据到智能未来的钥匙
  • CMake入门及生成windows下的项目示例讲解
  • Postman 请求头详解:快速掌握
  • flutter 获取设备的唯一标识
  • 国产 FPGA 的崛起之路,能否打破 Xilinx 的垄断?
  • nodejs-原型污染链
  • 基于核选择融合注意力机制TCN-MTLATTENTION-MAMBA模型(Python\matlab代码)
  • 【点盾云】加密技术如何防止视频内容随意传播?
  • Windows卸载以压缩包形式安装的MySQL
  • qt+opengl 加载三维obj文件
  • 跨网段投屏(by quqi99)
  • STM32编写触摸按键
  • 安全工具膨胀的隐性成本及其解决方法
  • 使用string和string_view(二)——数值转换、std::string_view和非标准字符串
  • Flutter常用功能教程:新手入门指南