Golang文件操作

文件操作

基本介绍

基本介绍

  • 文件操作是指对计算机文件进行读取、写入、修改、删除和移动等操作的过程,它可以用于读取配置文件、存储日志、处理用户上传的文件等,Go中主要通过os和bufio包提供文件操作功能。
  • 文件在程序中是以流的形式进行操作的,我们把数据在数据源(文件)和程序(内存)之间经历的路径叫做流。其中数据从数据源到程序的路径叫做输入流,数据从程序到数据源的路径叫做输出流。

文件流示意图如下:

在这里插入图片描述

普通的文件操作方式(os包)

os包介绍

在os包中,File类型代表一个打开的文件,其封装了与文件相关的操作和属性。File结构体的定义如下:

type File struct {
   
	*file // os specific
}

File结构体中以*type的方式嵌套了file类型的匿名结构体指针,实际文件的属性信息都存储在file结构体中。file结构体的定义如下:

type file struct {
   
	pfd         poll.FD
	name        string
	dirinfo     atomic.Pointer[dirInfo] // nil unless directory being read
	nonblock    bool                    // whether we set nonblocking mode
	stdoutOrErr bool                    // whether this is stdout or stderr
	appendMode  bool                    // whether file is opened for appending
}

file结构体各字段说明:

  • pfd:用于与底层的操作系统文件描述符进行交互。
  • name:表示文件的名称(包括路径)。
  • dirinfo:用于在读取目录时缓存目录的信息(打开的文件是目录时被使用)。
  • nonblock:表示文件是否设置为非阻塞模式。
  • stdoutOrErr:表示文件是否是标准输出或标准错误。
  • appendMode:表示文件是否以追加模式打开。

每一个打开的文件都对应一个文件描述符,file结构体中的pfd是poll.FD类型的,实际文件对应的文件描述符就存储在poll.FD结构体的Sysfd字段中。FD结构体的定义如下:

type FD struct {
   
	// Lock sysfd and serialize access to Read and Write methods.
	fdmu fdMutex

	// System file descriptor. Immutable until Close.
	Sysfd int

	// Platform dependent state of the file descriptor.
	SysFile

	// I/O poller.
	pd pollDesc

	// Semaphore signaled when file is closed.
	csema uint32

	// Non-zero if this file has been set to blocking mode.
	isBlocking uint32

	// Whether this is a streaming descriptor, as opposed to a
	// packet-based descriptor like a UDP socket. Immutable.
	IsStream bool

	// Whether a zero byte read indicates EOF. This is false for a
	// message based socket connection.
	ZeroReadIsEOF bool

	// Whether this is a file rather than a network socket.
	isFile bool
}

打开文件

在os包中,使用OpenFile函数打开文件,该函数的函数原型如下:

func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

参数说明:

  • name:表示需要打开的文件名称(包括路径)。
  • flag:表示打开文件的方式。
  • perm:表示新创建文件的权限,通常设置为0666(表示任何人都可读写,不可执行)。

返回值说明:

  • file:如果打开文件成功,将返回文件对应的File结构体。
  • err:如果打开文件过程中出错,将返回非nil的错误值。

打开文件的方式可以使用以下标注之一或它们的组合。如下:

参数选项 含义
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以读写方式打开文件
O_APPEND 以追加的方式打开文件
O_CREATE 如果文件不存在,则创建文件
O_EXCL 与O_CREATE一起使用,确保创建新文件时不会覆盖现有文件
O_SYNC 在每次写入操作后同步文件内容到磁盘
O_TRUNC 如果文件已存在,将截断文件为零长度

打开文件示例如下:

package main

import (
	"fmt"
	"os"
)

func main() {
   
	name := `D:\github\Golang-topics\src\go_code\FileOperation\FileOperation\NormalOperation\data.txt`
	// 打开文件
	file, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
   
		fmt.Printf("open file error, err = %v\n", err)
		return
	}
	fmt.Printf("open file success, fd = %v\n", file.Fd()) // open file success, fd = 420
}

说明一下:

  • 通过File结构体的Fd方法,可以获取该文件对应的文件描述符。文件的文件描述符由底层操作系统分配,每次打开文件时分配的文件描述符可能不同。

关闭文件

在os包中,使用File结构体的Close方法关闭文件,该方法的原型如下:

func (f *File) Close() error

返回值说明:

  • 关闭文件成功返回nil,否则返回非nil的错误值。

关闭文件示例如下:

package main

import (
	"fmt"
	"os"
)

func main() {
   
	name := `D:\github\Golang-topics\src\go_code\FileOperation\FileOperation\NormalOperation\data.txt`
	// 1、打开文件
	file, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
   
		fmt.Printf("open file error, err = %v\n", err)
		return
	}
	// 2、延迟关闭文件
	defer file.Close()
}

说明一下:

  • 文件操作完毕后需要及时调用Close方法对文件进行关闭,避免造成文件描述符泄露。
  • 通常利用defer机制对文件进行延迟关闭,在defer语句之后仍然可以操作文件,文件将会在函数执行完毕后自动关闭。

获取文件属性信息

在os包中,使用File结构体的Stat方法获取文件的属性信息,该方法的原型如下:

func (f *File) Stat() (fi FileInfo, err error)

返回值说明:

  • fi:如果方法调用成功,将返回文件的属性信息。
  • err:如果方法调用过程中出错,将返回非nil的错误值。

Stat方法获取到的文件信息FileInfo是一个接口类型,该类型的定义如下:

type FileInfo interface {
   
	Name() string       // base name of the file
	Size() int64        // length in bytes for regular files; system-dependent for others
	Mode() FileMode     // file mode bits
	ModTime() time.Time // modification time
	IsDir() bool        // abbreviation for Mode().IsDir()
	Sys() any           // underlying data source (can return nil)
}

FileInfo接口中各方法说明:

  • Name方法:返回文件的基本名称(不包含路径)。
  • Size方法:返回文件的大小。
  • Mode方法:返回文件的权限和模式位信息。
  • ModTime方法:返回文件最后一次修改时间。
  • IsDir方法:判断文件是否是一个目录。
  • Sys方法:返回底层数据源,通常是操作系统特定的文件信息(可能返回nil)。

获取文件属性信息示例如下:

package main

import (
	"fmt"
	"os"
)

func main() {
   
	name := `D:\github\Golang-topics\src\go_code\FileOperation\FileOperation\NormalOperation\data.txt`
	// 1、打开文件
	file, err := os.OpenFile(name, os.O_RDONLY, 0666)
	if err != nil {
   
		if os.IsNotExist(err) {
   
			fmt.Println("warning: file not exists...")
		} else {
   
			fmt.Printf("open file error, err = %v\n", err)
		
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2021dragon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值