(二)常用内置函数

文件系统

当前文件偏移量【指针】 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
相关推荐
Sinclair26 分钟前
认识安企CMS-系统概述
开源·go
cocoCola916675 小时前
Golang中的接口
go
赫媒派7 小时前
Gin 12年零破坏API,架构哲学如何练成?
后端·go·gin
唐青枫11 小时前
别再只会 if err != nil:Go error 从错误链到工程实战详解
go
小满zs1 天前
Go语言第二章(小无相功)
后端·go
妙码生花1 天前
从 PHP 到 AI + Golang,程序员自救转型手记(十九):点选验证码代码逐行目检
前端·后端·go
老鹰8621 天前
Google Wire 被官方抛弃,Uber Fx 启动就 panic,Go DI 还有救吗?
go
golang学习记1 天前
Go面试官:说说struct{}为什么占用0字节
go
喵个咪2 天前
Go Wind UBA 拆解系列 - 架构总览:三服务、数据流与契约优先
大数据·后端·go
喵个咪2 天前
Go Wind UBA 拆解系列 - 多租户与安全:两套隔离机制的边界
大数据·后端·go