17、做中学 | 初三下期 Golang文件操作

走到这里的探索者们,对电脑是相当了解的,接下来用go和系统来次对话!

一、go的角度认识文件

1. 什么是文件

在面向对象编程语言中,一切皆对象,而在操作系统(如:Linux)一切皆文件!我们记录的txt文件,办公的excel文件,拍的照片jpg文件,录的语音mp4文件,拍的视频mp4文件…都是文件。他们都是进行保存我们的数据。

2. 输入流/输出流

编程操作文件的过程,是通过流的形式进行操作的!
在这里插入图片描述
图中出现了“流”的概念,和流的经历的路径,具体意思如下:

流:数据在数据源(文件)和程序(内存)之间经历的路径 (上班下班来回路线)
输入流:数据从数据源(文件)到程序(内存)的路径 (从家到公司的路线)
输出流:数据从程序(内存)到数据源(文件)的路径 (从公司到家的路线)

站在了内存的角度去看流的方向

二、文件操作

https://studygolang.com/pkgdoc
os包File结构体下,有一些公用的文件操作方法
在这里插入图片描述

1. 打开/关闭文件

1.1 打开文件

根据官网学习网站,os包File结构体下需要调用这个方法,进行打开文件

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

在d盘新建一个txt文档,进行打开文件

	// 返回file指针对象,err为异常接收
	file, err := os.Open("d:\\file.txt")

	// 进行处理接收的异常 这里直接结束main
	if err != nil {
		return
	}

	fmt.Printf("file: %v", file)

来到了公司(内存),我们不能一直上班,这时需要打卡下班…

1.2 关闭文件(有打开必有关闭)

打卡下班!!!

func (f *File) Close() error

没有入参,返回抛出的异常。

	// 关闭文件 接收抛出的异常
	err = file.Close()

	// 异常处理  这里直接打印
	if err != nil {
		fmt.Println(err)
	}

2. 读文件

2.1 读取小文件

一次性加载全部内容到内存,适合读取小文件

package main

import (
	"fmt"
	"os"
)

func main() {
	file, err := os.ReadFile("d:\\file.txt")
	if err != nil {
		return
	}
	fmt.Println(string(file))
	//《泊船瓜洲》
	//宋朝·王安石
	//京口瓜洲一水间,钟山只隔数重山。
	//春风又绿江南岸,明月何时照我还。
}

2.2 按行读取文件

获取到文件对象,进行每行内容加载到内存,适合大文件

bufio 优化性能:通过缓冲减少 I/O 操作次数,适合频繁读写。

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 打开文件
	file, err := os.Open("d:\\file.txt")
	if err != nil {
		return
	}

	// 关闭文件
	defer file.Close()

	// 读取文件
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
		fmt.Println("------------------")
	}

	if scanner.Err() != nil {
		fmt.Println(scanner.Err())
	}
	//《泊船瓜洲》
	//------------------
	//宋朝·王安石
	//------------------
	//京口瓜洲一水间,钟山只隔数重山。
	//------------------
	//春风又绿江南岸,明月何时照我还。
	//------------------
}

3. 写文件

3.1 小文件写入

打开文件并写入,使用OpenFile方法进行模式选择和权限赋予

package main

import (
	"fmt"
	"os"
)

func main() {
	// 打开文件的同时 如果有则进行清空写入 无则进行创建并写入
	file, err := os.OpenFile("d:\\writerfile.txt", os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()

	// 写入一个文件 提前创建了一个空文件
	file.WriteString("hello golang2\n")
}

上边我们看到OpenFile方法中入参有俩个陌生的参数,模式和参数

打开文件模式列表如下

必须项:必须指定O_RDONLY、O_WRONLY或O_RDWR中的一个。

  1. O_RDONLY int=syscall.O_RDONLY //以只读方式打开文件。
  2. O_WRONLY int=syscall.O_WRONLY //以写方式打开文件。
  3. O_RDWR int=syscall.O_RDWR //以读写方式打开文件。

可选项:其余的值可以被输入或输入以控制行为。

  1. O_APPEND int=syscall.O_APPEND //写入时向文件追加数据。
  2. O_CREATE int=syscall.O_CREAT //如果不存在,则创建一个新文件。
  3. O_EXCL int=syscall.O_EXCL //与O_CREATE一起使用时,文件必须不存在。
  4. O_SYNC int=syscall.O_SYNC //打开同步I/O。
  5. O_TRUNC int=syscall.O_TRUNC //打开时截断常规可写文件。

我使用了创建文件O_CREAT模式 和写入O_WRONLY模式,想创建文件并写人内容!

第二个陌生的参数是0666是什么意思呢?这个熟悉Linux的探索者们一定不陌生,这个就是文件的权限
在这里插入图片描述
所以你需要什么权限相加就行,0666意思如下
0:代表八进制
6:所有者拥有r(读)和w(写)权限
6:所属组拥有r(读)和w(写)权限
6:其他人拥有r(读)和w(写)权限

3.2 按行写入

package main

import (
	"bufio"
	"os"
)

func main() {
	// 打开文件
	file, err := os.Create("d:\\fileWriterLine.txt")
	if err != nil {
		return
	}

	// 关闭文件
	defer file.Close()

	// 写入文件
	writer := bufio.NewWriter(file)
	arr := []string{
		"《泊船瓜洲》",
		"宋朝·王安石",
		"京口瓜洲一水间,钟山只隔数重山。",
		"春风又绿江南岸,明月何时照我还。",
	}
	for _, line := range arr {
		writer.WriteString(line)
		writer.WriteString("\n")
	}

	writer.Flush()
}

为什么最后会有个Flush方法呢?原因是NewWriter是带缓存的,进行批次写入,就像十字路口攒了一批人,可以闯红灯一样…

三、小练习

了解了怎么文件是什么,如何通过go去操作文件,那么开始来个小练习
练习内容如下

	// 1. 创建一个文件
	// 2. 按行写入
	// 3. 追加写入时间
	// 4. 进行文件重命名
	// 5. 按行读取文件
	// 6. 删除文件

根据上边的需求内容,进行编写

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 1. 创建一个文件
	// 2. 按行写入
	// 3. 追加写入时间
	// 4. 进行文件重命名
	// 5. 按行读取文件
	// 6. 删除文件

	// 1. 创建一个文件
	fileWriter, err := os.OpenFile("d:\\file.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Printf("open file failed, err:%v\n", err)
		return
	}

	// 2. 按行写入文件
	writer := bufio.NewWriter(fileWriter)
	arr := []string{
		"《泊船瓜洲》",
		"宋朝·王安石",
		"京口瓜洲一水间,钟山只隔数重山。",
		"春风又绿江南岸,明月何时照我还。",
	}
	for _, line := range arr {
		writer.WriteString(line)
		writer.WriteString("\n")
	}

	writer.Flush()

	// 3. 追加写入时间
	fileWriter.WriteString("\n" + "2021-09-02 15:05:05")
	fileWriter.Sync()

	// 方法结束后,进行关闭文件
	fileWriter.Close()

	// 4. 文件重命名
	err = os.Rename("d:\\file.txt", "d:\\fileTest.txt")
	if err != nil {
		fmt.Printf("rename file failed, err:%v\n", err)
		return
	}

	// 5. 按行读取文件
	fileRead, err := os.Open("d:\\fileTest.txt")
	if err != nil {
		fmt.Printf("open file failed, err:%v\n", err)
		return
	}
	// 按行读取
	scanner := bufio.NewScanner(fileRead)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
		fmt.Println("------------")
	}
	if scanner.Err() != nil {
		fmt.Println(scanner.Err())
	}

	// 关闭读文件流
	fileRead.Close()

	// 6. 删除文件
	err = os.Remove("d:\\fileTest.txt")
	if err != nil {
		fmt.Printf("remove file failed, err:%v\n", err)
		return
	}

}

文件其它方法调用方法大致相同,在特定的场景和需求下,进行合理使用!本篇为引导篇,不做全部列举!

平常电脑操作的文件的时候,我们都是通过鼠标右键,选择功能进行操作!

现在学了go,我们站在了go的角度,去思考和操作文件和文档!

文件/文档:大致生命流程,创建–重命名–修改权限–阅读/修改内容–删除

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值