Go进阶—file文件操作

TOC

一、file文件操作

Go 语言提供了丰富的标准库来支持文件处理,包括文件的打开、关闭、读取、写入、追加和删除等操作。

  1. os是核心库:提供底层文件操作(创建、读写、删除等),大多数场景优先使用。
  2. io提供通用接口:如 Reader/Writer,可与文件、网络等数据源交互。
  3. bufio优化性能:通过缓冲减少 I/O 操作次数,适合频繁读写。
  4. ioutil已弃用:Go 1.16 后其功能迁移到 os 和 io 包。
  5. path/filepath处理路径:跨平台兼容(Windows/Unix 路径分隔符差异)。

os库对文件的操作

打开文件(Open和OpenFile)

Open()方法

方法说明:

func Open(name string) (*File, error)

以只读方式打开文件(不能写入),返回 *os.File 类型和 error。
【示例】代码如下所示:

func open_file() {
	// 打开文件,只读
	f, err := os.Open("test.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	// 创建一个1KB的缓冲区来存储读取的数据
	buf := make([]byte, 1024)
	bytes, err := f.Read(buf)
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	// 打印缓存大小和缓存区存储的读取内容
	fmt.Println("Read bytes:", bytes)
	fmt.Println("Content:", string(buf[:data]))
}
open_file()

OpenFile()方法

方法说明:

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

以读写的方式打开文件。flag的参数有:os.O_RDONLY, os.O_WRONLY, os.O_RDWR, os.O_CREATE, os.O_APPEND, os.O_TRUNC,perm:权限(如 644)。
【示例】代码如下所示:

func open_file_rw() {
	// 打开文件并设置权限
	f, err := os.OpenFile("test.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	// 追加内容写入
	f.WriteString("追加一行日志\n")
	// 移动文件指针到开头,以便读取内容,否则会读取报错
	_, err = f.Seek(0, 0) // 将指针移动到文件开始
	if err != nil {
		fmt.Println("Error seeking to start:", err)
		return
	}
	// 创建一个1KB的缓冲区来存储读取的数据
	buf := make([]byte, 1024)
	bytes, err := f.Read(buf)
	if err != nil {
		fmt.Println("Error reading file:", err)
		return
	}
	// 打印缓存大小和缓存区存储的读取内容
	fmt.Println("Read bytes:", bytes)
	fmt.Println("Content:", string(buf[:bytes]))
}
open_file_rw()

其他文件操作

获取文件信息

方法说明:

func Stat(name string) (*File, error)

返回的File对象再调用相关方法获取对应的有用信息。
【示例】代码如下所示:

func get_file_info() {
	file, err := os.Stat("test.txt")
	if err != nil {
		fmt.Println("Error reading file:", err)
	}
	fmt.Println("文件大小:", file.Size())
	fmt.Println("是否是目录:", file.IsDir())
	fmt.Println("最后修改时间:", file.ModTime())
	fmt.Println("文件权限:", file.Mode())
}
get_file_info()

删除文件

方法说明:

func Remove(name string) error

使用os.Remove()方法删除。
【示例】代码如下所示:

os.Remove("test.txt")

重命名文件

方法说明:

func Rename(old_name, new_name string) error

使用os.Rename()方法修改名字。
【示例】代码如下所示:

os.Rename("old_name.txt", "new_name.txt")

创建目录

方法说明:

func Mkdir(name string, mod int) error
// 递归创建多层目录
func MkdirAll(name string, mod int) error

可以通过Mkdir()和MkdirAll()方法分别来创建单个目录或者递归创建多层目录,需要注意创建条件。
【示例】代码如下所示:

os.Mkdir("a", 0755)
// 递归创建多层目录
os.MkdirAll("a/b/c", 0755)

删除目录

方法说明:

// 删除空目录
func Remove(name string) error
// 递归删除多层目录,以及所有内容
func RemoveAll(name string) error

【示例】代码如下所示:

os.Remove("test")       // 删除空目录
os.RemoveAll("test")     // 删除目录及其所有内容(慎用)

更改文件权限

方法说明:

func Chmod(name string, mod int) error

使用os.Chmod()方法更改文件权限。
【示例】代码如下所示:

os.Chmod("file.txt", 0644)

io库对文件的操作

复制数据

方法说明:

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

从Reader复制数据到Writer(如文件复制)。
【示例】代码如下所示:

func copy_file() {
	// 获取源文件对象
	srcFile, err := os.Open("test.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer srcFile.Close()
	// 获取目的文件对象
	dstFile, err := os.Create("test1.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer dstFile.Close()
	// 执行Copy()方法进行复制数据
	_, err = io.Copy(dstFile, srcFile)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("文件复制成功")
}
copy_file()

读取文件所有数据

方法说明:

ReadAll(r Reader) ([]byte, error)

从Reader读取所有数据(类似 os.ReadFile,但针对接口)
【示例】代码如下所示:

func read_all() {
	// 使用os.Open()打开文件
	file, err := os.Open("test.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	// 使用io.ReadAll()读取文件内容
	content, err := io.ReadAll(file)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(content))
}
read_all()

bufio库对文件的操作

逐行读取文件

方法说明:

func NewReader(r Reader) *Reader

创建带缓冲的读取器(提高大文件读取效率)
【示例】代码如下所示:

func read_line() {
	// 打开文件
	file, err := os.Open("test.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	// 使用bufio.NewReader()方法逐行读取
	reader := bufio.NewReader(file)
	i := 1
	// 配合for循环打印出每行内容
	for {
	    // ReadString('\n') 会在每一行末尾保留换行符:\n
		line, err := reader.ReadString('\n')
		if err != nil {
			break
		}
		fmt.Printf("读取第 %d 行: %v", i, line)
		i++
	}
}
read_line()

使用ReadLine()进行逐行读取
【示例】代码如下所示:

func realine() {
	file, _ := os.Open("test.txt")
	defer file.Close()

	reader := bufio.NewReader(file)
	i := 1
	// 利用for循环逐行打印每行的数据
	for {
		// line是每行的数据,isPeefix是是否读完该行的数据状态
		line, isPrefix, err := reader.ReadLine()
		if err != nil {
			break
		}
		// isPrefix 为 true 说明行还没读完(太长)
		fmt.Println("读取第", i, "行:", string(line), "--是否存在未读完:", isPrefix)
		i++
	}
}
readline()

逐行读取文件(高效推荐)

方法说明:

NewScanner(rd io.Reader) *Scanner

创建逐行扫描器(适合逐行读取)。更简单且自动处理分行,推荐用来处理文本日志、CSV 等。
【示例】代码如下所示:

func read_line_scanner() {
	// 打开文件对象
	file, err := os.Open("test.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	// 使用bufio.NewScanner()逐行读取文件
	scanner := bufio.NewScanner(file)
	i := 1
	// 利用for循环打印出每一行的数据
	for scanner.Scan() {
		line := scanner.Text() // 不包括换行符
		fmt.Printf("读取第 %d 行: %v\n", i, line)
		i++
	}
	// 如果读取失败则报错
	if err := scanner.Err(); err != nil {
		fmt.Println("读取出错:", err)
	}
}
read_line_scanner()

写入文件

NewWriter(w io.Writer) *Writer

创建带缓冲的写入器(提高写入效率)。会先写入缓冲区,一定要调用Flush(),否则不会真正写入到磁盘。
【示例】代码如下所示:

func write_file() {
	// 创建并打开文件对象
	file, err := os.Create("output.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	// 使用bufio.NewWriter()创建对象
	writer := bufio.NewWriter(file)
	// 调用WriteString()写入内容
	writer.WriteString("第一行内容\n")
	writer.WriteString("第二行内容\n")

	// 必须刷新,否则内容可能只在缓冲区
	writer.Flush()
}
write_file()

逐行复制拷贝文件示例

使用bufio.NewScanner()bufio.NewWriter()方法实现文件的复制拷贝。
【示例】代码如下:

func new_copy_file() {
	// 获取源文件对象
	srcFile, err := os.Open("test.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer srcFile.Close()
	// 获取目的文件对象
	dstFile, err := os.Create("test1.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer dstFile.Close()
	// 初始化创建读取和写的对象
	scanner := bufio.NewScanner(srcFile)
	writer := bufio.NewWriter(dstFile)
	// 利用for循环逐行读取源文件数据写入到目的文件
	for scanner.Scan() {
	    line := scanner.Text()
	    writer.WriteString(line + "\n")
	}
	writer.Flush()
	return scanner.Err()
}
new_copy_file()