(二)常用内置函数

文件系统

当前文件偏移量【指针】 Current Offset

当打开或者创建一个文件时,都会有文件偏移量,用以度量从文件开始处计算的字节数,通常,读,写操作都是从当前文件偏移量开始,并使偏移量增加所读写的字节数.按照系统默认情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0

文件读取完毕后指针会指向文件尾部,此时再进行读取是读不到东西的

io.Copy(dst io.Writer, src io.Reader) (written int64, err error)

接受两个参数:一个可写源,一个可读源

go 复制代码
func FileOperate() {
	sourceFile, err := os.Open("./fileSys/demo.txt")
	if err != nil {
		fmt.Println(err)
	}

	targetFile, err := os.Create("./fileSys/demo1.txt")
	targetFile2, err := os.Create("./fileSys/demo2.txt")

	io.Copy(targetFile, sourceFile)  // 成功将demo.txt的内容复制到了demo1
	io.Copy(targetFile2, sourceFile) // 没有复制到任何东西
}

上面的代码,执行过一次Copy后,sourceFile的指针指向文件尾部,再进行赋值,读取不到任何内容了,想要继续copy到内容,需要将文件指针指向文件头部:

go 复制代码
...
...
io.Copy(targetFile, sourceFile)
sourceFile.Seek(0,io.SeekStart) // 将文件指针移到头部
io.Copy(targetFile2, sourceFile)

// 或者调用os.Open()再次打开文件

File.ReadFrom(r io.Reader) (n int64, err error)

将读取的数据写入到文件中,和io.Copy类似,io.Copy内部一般也是调用此方法,进行操作

go 复制代码
func FileOperate() {
	sourceFile, err := os.Open("./fileSys/demo.txt")
	if err != nil {
		fmt.Println(err)
	}

	targetFile, err := os.Create("./fileSys/demo1.txt")
	targetFile2, err := os.Create("./fileSys/demo2.txt")

	targetFile.ReadFrom(sourceFile)
	sourceFile.Seek(0, io.SeekStart)// 指针重置到文件头部
	targetFile2.ReadFrom(sourceFile)
}

File.ReadAt(b []byte, off int64) (n int, err error)

从文件off指定偏移位置尝试读取n个字节长度的内从到切片b中,如果读取成功返回读取的长度n,失败返回err,这个方法不会自动更新文件的偏移量,下次读取依旧从指定的位置开始

File.Read(b []byte) (n int, err error)

从文件头部开始读取n个字节的内容到切片b中,如果读取成功返回读取的长度n,失败返回err,这个方法会自动更新文件偏移量,下一次将从上次一读取结束的地方开始

File.Write(b []byte) (n int, err error)

向文件中写入内容

go 复制代码
// 同样以上面文件copy为例
func FileOperate() error {

	sourceFile, err := os.Open("./fileSys/demo.txt")
	if err != nil {
		fmt.Println(err)
	}

	sourceFileInfo, err := sourceFile.Stat()

	if err != nil {
		return err
	}

	buffer := make([]byte, sourceFileInfo.Size())

	sourceFile.Read(buffer)

	targetFile, err := os.Create("./fileSys/demo1.txt")
	targetFile2, err := os.Create("./fileSys/demo2.txt")

	targetFile.Write(buffer)
	targetFile2.Write(buffer)
	return nil
}
  • 上面方式读取大文件可能会有性能问题,换另一种方式:
go 复制代码
func FileOperate() error {

	sourceFile, err := os.Open("./fileSys/demo.txt")
	if err != nil {
		fmt.Println(err)
	}

	targetFile, err := os.Create("./fileSys/demo1.txt")
	targetFile2, err := os.Create("./fileSys/demo2.txt")

	buffer := make([]byte, 1024)

	for {
		n, err := sourceFile.Read(buffer)
		if err != nil {
			break
		}
		if n > 0 {
			// 可能读不满1024个字节,所以要根据实际截取
			targetFile.Write(buffer[0:n])
			targetFile2.Write(buffer[0:n])
		}
	}

	return nil
}

判断文件、目录是否存在

go 复制代码
if file, err := os.Stat("./fileSys/asdf/demo45.txt"); err == nil || os.IsExist(err) {
    fmt.Println("文件存在", file)
    return
} 
fmt.Println("文件不存在")
// 或者使用os.IsNotExist判断

其他内置函数

时间格式化

骚气的格式化方法,和js不同,不能用YYYY-MM-DD HH:mm:ss的形式,而是要传入一个指定格式实际日期模板,例如:2022-01-02 15:20:32
尤其注意时分秒格式化:时间模板3代表12小时制,15代表24小时制

go 复制代码
// 获取当前时间并格式化成指定日期(12小时制)
t := time.Now().Format("20060102_030405")
fmt.Println(t) // 输出:20230829_111650

// 获取当前时间并格式化成指定日期(24小时制)
t := time.Now().Format("20060102_150405")
fmt.Println(t) // 输出:20230829_111650
相关推荐
未来魔导4 小时前
go语言中json操作总结
数据分析·go·json
王中阳Go背后的男人9 小时前
GoFrame vs Laravel:从ORM到CLI工具的全面对比与迁移指南
后端·go
卡尔特斯11 小时前
Go 安装插件更换国内镜像
go
王中阳Go11 小时前
都2026年了,PHP还纠结转Go还是Java呢?安利一个无缝迁移的框架~
java·后端·go
卡尔特斯11 小时前
go get 快速入门(自用笔记)
go
得物技术13 小时前
Go语言在高并发高可用系统中的实践与解决方案|得物技术
go
喵个咪16 小时前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:深度解析 Wire 依赖注入集成实践
后端·go
喵个咪1 天前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:JWT 集成指南
后端·go
喵个咪1 天前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:OPA 集成指南:从原理到实践
后端·go
喵个咪1 天前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:Casbin集成指南
后端·go