Go 1.16起ioutil包被彻底移除,需迁移到os/io包:os.WriteFile需用0o644权限并手动创建父目录;os.CreateTemp/os.MkdirTemp首参不能为"";os.ReadDir返回os.DirEntry需调用Info()获取元数据;io.ReadAll等直接替换但须删除io/ioutil导入。

Go 1.16 起 ioutil 包已彻底移除,不是警告,是编译失败——所有 ioutil.ReadFile、ioutil.TempFile 等调用会直接报 undefined: ioutil。
os.ReadFile 和 os.WriteFile 的权限与路径陷阱
旧代码写 ioutil.WriteFile("data/logs/app.log", data, 0644),迁移到 os.WriteFile 后必须改两处:
-
0644→ 改为0o644(缺0o前缀会被当十进制 420,生成错误权限) - 如果
"data/logs"目录不存在,os.WriteFile不会自动创建父目录,会直接 panic:open data/logs/app.log: no such file or directory
正确做法是提前调用 os.MkdirAll("data/logs", 0o755);os.ReadFile 虽不写文件,但路径中含不存在目录时也会同样失败(比如读 "config/local.yaml" 而 config/ 不存在)。
os.CreateTemp 和 os.MkdirTemp 的参数顺序和空字符串 panic
os.CreateTemp(dir, pattern) 和 os.MkdirTemp(dir, pattern) 第一个参数是父目录路径,不能传空字符串 ""——这和旧版 ioutil.TempDir("", "prefix") 行为不兼容,但 Go 不再容忍。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
立即学习“go语言免费学习笔记(深入)”;
- 错:
os.CreateTemp("", "tmp-*.log")→ panic:mkdir: invalid argument - 对:
os.CreateTemp(os.TempDir(), "tmp-*.log") - 临时文件创建后务必显式
defer f.Close()和os.Remove(f.Name()),否则泄漏风险高
os.ReadDir 替代 ioutil.ReadDir 时的类型差异
ioutil.ReadDir 返回 []fs.FileInfo,而 os.ReadDir 返回 []os.DirEntry,二者接口不同,不能直接替换。
-
os.DirEntry是轻量级接口,不强制读取完整元数据;要获取修改时间或大小,需先调用entry.Info() - 常见误写:
for _, fi := range entries { fmt.Println(fi.ModTime()) }→ 编译报错,因为fi是os.DirEntry,没有ModTime()方法 - 正确写法:
if info, err := entry.Info(); err == nil { fmt.Println(info.ModTime()) }
io.ReadAll 和 io.NopCloser 迁移最简单,但别漏掉包导入
ioutil.ReadAll → io.ReadAll,ioutil.NopCloser → io.NopCloser,签名和行为完全一致,只需改导入和函数名。
- 容易忽略的是:旧代码可能同时 import
"io/ioutil"和"io",迁移后必须删掉"io/ioutil",否则即使没用到也会触发 deprecated 警告(Go 1.22+ 将彻底禁止) -
io.Discard同理,替代ioutil.Discard,无需额外处理
最常被跳过的细节是:临时文件/目录的清理逻辑没跟着改——os.CreateTemp 创建的文件不会自动删除,os.MkdirTemp 创建的目录也不会自动递归清除,这些责任现在完全落在调用方身上。

















