Go开发指南:io/ioutil包应用和迁移指南

概览

Go语言的标准库中,ioutil在文件和I/O操作中扮演者重要的角色。虽然从Go 1.16版本开始,Go团队认为ioutil是一个定义不清且难以理解的程序集合,所有功能的实现代码迁移至ioos包。

鉴于ioutil的功能已被标记为废弃,推荐使用新的API,本文在介绍ioutil应用时会相应介绍新的API如何使用。

新旧函数对照表

为确保代码平滑过渡,io/ioutil在Go 1.16+中通过包装新包函数实现兼容。通过阅读io/ioutil/ioutil.goio/ioutil/tempfile.go源码,梳理出新旧版本函数对照表:

原函数 新函数 返回值差异 功能说明
ioutil.Discard io.Discard
ioutil.NopCloser io.NopCloser
ioutil.ReadAll io.ReadAll
ioutil.ReadDir os.ReadDir []fs.FileInfo → []os.DirEntry
ioutil.ReadFile os.ReadFile 读取指定文件的全部内容
ioutil.TempDir os.MkdirTemp 读取指定目录下的文件和目录信息
ioutil.TempFile os.CreateTemp
ioutil.WriteFile os.WriteFile 将指定数据写入指定文件

io/ioutil函数应用

ReadFile

在Go中,读取文件通常需要几个步骤:打开文件->读取文件->关闭文件io/ioutilReadFile函数可以简化该过程,避免手动打开和关闭文件,简化了错误处理,适用于小文件

新旧函数示例代码

go 复制代码
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	var fileName = "data.txt"
	data, err := ioutil.ReadFile(fileName)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(data))

	// go1.16后该功能由os.ReadFile实现,入参和返回值与旧函数保持一致
	data, err = os.ReadFile(fileName)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(data))
}

WriteFile

io/ioutilWriteFile将指定数据写入指定文件,如果文件不存在则创建文件后写入,如果文件中含有内容,则会覆盖原有的内容。

新旧函数示例代码

go 复制代码
package main

import (
	"io/ioutil"
	"log"
	"os"
)

func main() {
	var fileName = "data.txt"
	data := []byte("Class: No.1")
	err := ioutil.WriteFile(fileName, data, 0644)
	if err != nil {
		log.Fatal(err)
	}

	// go1.16后该功能由os.WriteFile实现,入参和返回值与旧函数保持一致
	data = []byte("Class: No.2")
	err = os.WriteFile(fileName, data, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

ReadDir

io/ioutilReadDir读取指定目录下所有目录和文件信息,并返回fs.FileInfo数组。新函数则是返回os.DirEntry数组

返回值结构体对比

FileInfo DirEntry 说明
Name() Name() 获取文件或者目录名
IsDir() IsDir() 是否为文件夹
Mode() Type() 类行位
Info() 返回FileInfo
Size() 通过Info()获取FileInfo后再调用Size() 获取文件大小
ModTime() 通过Info()获取FileInfo后再调用ModTime() 获取文件修改时间
Sys() 通过Info()获取FileInfo后再调用Sys()

新旧函数示例代码

go 复制代码
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	path := "../test"
	files, err := ioutil.ReadDir(path)
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range files {
		fmt.Println(file.Sys())
	}
	fmt.Println("------")

	// go1.16后该功能由os.ReadDir实现,入参一致,返回值更改
	newfiles, err := os.ReadDir(path)
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range newfiles {
		info, _ := file.Info()
		fmt.Println(info.Sys())
	}
}
相关推荐
tang7778921 小时前
爬虫如何绕过绕过“5秒盾”Cloudflare:从浏览器指纹模拟到Rust求解之不完全指南
开发语言·爬虫·rust·cloudflare
Yuer202521 小时前
什么是 Rust 语境下的“量化算子”——一个工程对象的最小定义
开发语言·后端·rust·edca os·可控ai
hqwest21 小时前
码上通QT实战26--系统设置01-系统设置布局
开发语言·qt·qss·qt基础控件·qt布局控件·qt表格控件
薛定谔的猫198221 小时前
llama-index Embedding 落地到 RAG 系统
开发语言·人工智能·python·llama-index
短剑重铸之日21 小时前
《7天学会Redis》Day 5 - Redis Cluster集群架构
数据库·redis·后端·缓存·架构·cluster
计算机程序设计小李同学1 天前
基于SSM框架的动画制作及分享网站设计
java·前端·后端·学习·ssm
jghhh011 天前
传递对准MATLAB仿真程序
开发语言·matlab
+VX:Fegn08951 天前
计算机毕业设计|基于springboot + vue小型房屋租赁系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Victor3561 天前
Hibernate(43)Hibernate中的级联删除如何实现?
后端
Victor3561 天前
Hibernate(44)Hibernate中的fetch join是什么?
后端