IO输入输出
标准输入输出
fmt 包的 Println / Printf / Print 输出到标准输出(stdout),Scanln / Scanf 从标准输入读取。底层对应 os.Stdout、os.Stdin、os.Stderr 三个标准文件。
| 对象 | 说明 |
|---|---|
| os.Stdin | 标准输入,实现 io.Reader |
| os.Stdout | 标准输出,实现 io.Writer |
| os.Stderr | 标准错误输出,实现 io.Writer |
package main
import "fmt"
func main() {
var name string
fmt.Print("请输入名字: ")
fmt.Scanln(&name)
fmt.Printf("你好, %s\n", name)
}
日常输出用 fmt.Println,错误输出到 stderr 常用 log 包,log 默认写到 os.Stderr。
package main
import (
"fmt"
"os"
)
func main() {
var name string
fmt.Print("请输入名字: ")
fmt.Scanln(&name)
// 显式写入标准输出
fmt.Fprintf(os.Stdout, "你好, %s\n", name)
// 写入标准错误
fmt.Fprintln(os.Stderr, "这是一条错误信息")
}
bufio.Scanner 读输入
读取键盘输入时,fmt.Scanln 按空白分割,遇到空格会断开。用 bufio.Scanner 可以读取整行(含空格):
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 从标准输入读取
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("请输入一整行内容: ")
if scanner.Scan() {
line := scanner.Text() // 整行内容,含空格
fmt.Println("你输入的是:", line)
}
}
Scanner 默认最大行长度 64KB,超长行需要调用 scanner.Buffer(buf, maxSize) 扩大缓冲区。
io.Reader / io.Writer 接口
io.Reader 和 io.Writer 是 Go 最核心的两个接口,各只有一个方法:
| 接口 | 方法 | 说明 |
|---|---|---|
| io.Reader | Read(p []byte) (n int, err error) | 从数据源读数据到缓冲区 |
| io.Writer | Write(p []byte) (n int, err error) | 把缓冲区数据写到目标 |
文件、标准流、网络连接、内存 buffer 都实现了这两个接口,所以可以统一处理:
package main
import (
"fmt"
"io"
"os"
"strings"
)
func main() {
// 三种不同的数据源,都是 io.Reader
sources := []io.Reader{
strings.NewReader("内存字符串\n"), // strings.Reader
os.Stdin, // 标准输入
}
// os.Open 返回的 *os.File 也是 io.Reader
file, _ := os.Open("config.txt")
defer file.Close()
sources = append(sources, file)
buf := make([]byte, 1024)
for _, r := range sources {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
fmt.Println("读取失败:", err)
return
}
fmt.Printf("读到 %d 字节: %s\n", n, string(buf[:n]))
}
}
io 包在此基础上提供了一批通用工具函数:
| 函数 | 作用 |
|---|---|
| io.Copy(dst, src) | 把 Reader 的数据复制到 Writer |
| io.ReadAll(r) | 一次性读光 Reader 的全部数据 |
| io.CopyN(dst, src, n) | 只复制前 n 字节 |
| io.MultiReader(...) | 把多个 Reader 拼成一个顺序读取 |
io.Reader / io.Writer 是"小接口"的典范,标准库大量函数都接受这两个接口作为参数,这样同一份代码既能处理文件,也能处理标准流、网络连接、内存数据。