当前位置:网站首页>Go 言 Go 语,一文看懂 Go 语言文件操作
Go 言 Go 语,一文看懂 Go 语言文件操作
2022-08-04 15:17:00 【华为云】
️ 实战场景
本篇博客为大家再次带来 Go 语言的基础知识,这次要学习的内容是 Go 中的文件操作。
打开关闭文件
在 Go 中操作文件,首先要做的就是导入 os 模块,该模块中具备相关函数定义。
package mainimport ( "fmt" "os")func main() { // 打开文件 file, err := os.Open("./ca.txt") if err != nil { fmt.Println("文件打开失败", err) return } print(file) // 输出地址 0xc000006028 // 关闭文件 file.Close()}如果文件打开失败,直接展示错误信息,正确的话,会返回 file 对象的地址。
读取文件
使用 Read 函数读取文件,其定义如下所示:
func (f *File) Read(b [] byte)(n int,err error)从定义中可以发现,Read 函数会返回 2 个值,第一个是读取的字节数,第二个是当读取报错时,返回错误信息,示例代码如下所示:
package mainimport ( "fmt" "io" "os")func main() { // 打开文件 file, err := os.Open("./ca.txt") if err != nil { fmt.Println("打开文件失败,错误信息:", err) return } // 为了防止忘记关闭文件,可使用defer注册文件关闭语句 defer file.Close() // Read方法读取数据 var tmp = make([]byte, 128) // 读取文件 n, err := file.Read(tmp) // 碰到 io.EOF 表示文件读取到末尾 if err == io.EOF { fmt.Println("文件读取完毕") return } if err != nil { fmt.Println("读取文件失败,错误信息:", err) return } fmt.Printf("读取了 %d 字节数据\n", n) fmt.Println(string(tmp[:n]))}输出如下内容:
读取了 24 字节数据姓名:梦想橡皮擦读取到 24 个字节,标准的中文占 3 个字节。
但是上述代码最大的问题就是,我们给变量 tmp,即数组 tmp 仅设置了 128 字节,如果待读取的文件超过了改值,例如 txt 内容如下所示:
姓名:梦想橡皮擦1姓名:梦想橡皮擦2姓名:梦想橡皮擦3姓名:梦想橡皮擦4姓名:梦想橡皮擦5此时运行代码,就会发现 Read 函数读取到第 128 个字节的时候,就会停止读取,间接导致读取到的数据乱码。
读取了 128 字节数据姓名:梦想橡皮擦1姓名:梦想橡皮擦2姓名:梦想橡皮擦3姓名:梦想橡皮擦4姓名:梦想橡��解决该问题,需要用到 for 循环读取文件数据,代码如下:
package mainimport ( "fmt" "io" "os")func main() { // 打开文件 file, err := os.Open("./ca.txt") if err != nil { fmt.Println("打开文件失败,错误信息:", err) return } defer file.Close() // 声明一个 content 切片 var content []byte var tmp = make([]byte, 128) for { n, err := file.Read(tmp) if err == io.EOF { fmt.Println("文件读取完毕") break } if err != nil { fmt.Println("读取文件失败,错误信息:", err) return } // 追加数据 content = append(content, tmp[:n]...) } fmt.Println(string(content))}上述代码声明了一个动态数组,即切片,解决了读取数据不足的问题。
bufio 读取文件
该函数可以一次读取一行数据,示例代码如下:
func main() { file, err := os.Open("./ca.txt") if err != nil { fmt.Println("打开文件失败,错误信息:", err) return } defer file.Close() reader := bufio.NewReader(file) for { // 逐行读取数据 line, err := reader.ReadString('\n') if err == io.EOF { if len(line) != 0 { fmt.Println(line) } fmt.Println("文件读取完毕") break } if err != nil { fmt.Println("读取文件失败,错误信息:", err) return } fmt.Print(line) }}该函数与 Python 中的 readline 具备同样的效果,接下来演示一下读取整个文件,代码如下:
package mainimport ( "fmt" "io/ioutil")func main() { content, err := ioutil.ReadFile("./ca.txt") if err != nil { fmt.Println("打开文件失败,错误信息:", err) return } fmt.Println(string(content))}注意导入模块的时候,直接导入了 io 包中的 ioutil 函数。
写文件
使用 os.OpenFile() 函数可以指定模式打开文件,即可以写入的方式打开文件。
写入文件最常用的函数是 Write和 WriteString,示例代码如下所示:
package mainimport ( "fmt" "os")func main() { file, err := os.OpenFile("ca.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { fmt.Println("打开文件失败,错误信息:", err) return } defer file.Close() name := "橡皮擦" file.Write([]byte(name)) //写入字节切片 file.WriteString("梦想橡皮擦") //写入字符串}使用该方式写入文件,会覆盖之前的文件内容,查看结果可直接打开目录下的 ca.txt 进行查看。
我们将 os.OpenFile("ca.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) 中的参数进行单独的说明。
第一个参数表示文件名,第二个参数是打开文件的模式,具体模式如下所示:
os.O_WRONLY:只写;os.O_CREATE:创建文件;os.O_RDONLY:只读;os.O_RDWR:读写;os.O_TRUNC:清空;os.O_APPEND:追加。
可以看到与 Python 中的文件模式基本一致。
最后一个参数值 0666 表示文件权限(八进制),这与 linux 文件权限数字一致,读 r 等于 0,写 w 表示 2,执行 x 等于 1,所以 666 表示的是文件可读,可写。
在文件写入部分,还存在 bufio.NewWriter 整行写入,ioutil.WriteFile 整体写入等内容,可以学习的时候重点查阅一下。
你正在阅读 【梦想橡皮擦】 的博客
阅读完毕,可以点点小手赞一下
发现错误,直接评论区中指正吧
边栏推荐
- 郑轻新生校赛和中工选拔赛题解
- 1403. 非递增顺序的最小子序列
- 【Today in History】August 4: First female Turing Award winner; NVIDIA acquires MediaQ; first Cybersecurity Challenge completed
- This week to discuss the user experience: Daedalus Nemo to join Ambire, explore the encryption of the ocean
- 普法教育结合VR全景,直观感受和学习法治精神
- 杭电校赛(逆袭指数)
- C# SolidWorks二次开发---工程图简单版标注孔信息
- IP第十七天笔记
- Game network UDP + FEC + KCP
- leetcode:250. 统计同值子树
猜你喜欢

C# SolidWorks二次开发---工程图简单版标注孔信息

Technology sharing | Description of the electronic fence function in the integrated dispatching system

快速整明白Redis中的字典到底是个啥

1403. Minimum Subsequence in Non-Increasing Order

手搓一个“七夕限定”,用3D Engine 5分钟实现烟花绽放效果

leetcode:250. 统计同值子树

郑轻新生校赛和中工选拔赛题解

技术分享| 小程序实现音视频通话

基于数据库实现分布式锁
微软表示将向内部网络安全专家共享数据 为企业提供更安全保护
随机推荐
数据链路层-------以太网协议
我在羊毛和二手群里报复性消费
LeetCode_模拟_中等_498.对角线遍历
leetcode:251. 展开二维向量
leetcode:241. 为运算表达式设计优先级
leetcode:254. 因子的组合
华为云 & 达达,帮有情人“一键送达”
7 天找个 Go 工作,Gopher 要学的条件语句,循环语句 ,第3篇
leetcode: 255 Verify preorder traversal sequence binary search tree
Roslyn 节点的 Span 和 FullSpan 有什么区别
leetcode:215无序数组中找第k大的元素
leetcode:253. 至少需要多少间会议室
技术分享| 融合调度系统中的电子围栏功能说明
Roslyn 通过 nuget 统一管理信息
Hangzhou electric the competition team arrangement (ACM)
什么是 DevOps?看这一篇就够了!
Resharper 如何把类里的类移动到其他文件
ping的原理
全球电子产品需求放缓,三星手机越南工厂每周只需要干 3~4 天
leetcode: 241. Designing precedence for arithmetic expressions