目录
前言
计算机中的文件是存储在外部介质(硬盘)上的数据集合,文件分为文本文件和二进制文件。
1、打开和关闭文件
os.Open()函数能够打开一个文件,返回一个*File和一个err,对得到的文件示例close()方法能够关闭文件。
示例:
package main
import (
"fmt"
"os"
)
//文件的打开和关闭
func main() {
//打开当前目录下的abc.txt文件
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
} else {
fmt.Println("文件打开成功")
file.Close()
fmt.Println("文件关闭成功")
}
}
//运行结果为:
D:\goproject\src\dev_code\day25\demo1>go run main.go
文件打开成功
文件关闭成功
2、读取文件
接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0和io.EOF。
func (f *File) Read(b []byte) (n int,err error)
示例:
defer—般用于资源的释放和异常的捕捉。
defer语句会将其后面跟随的语句进行延迟处理;跟在defer后面的语言将会在程序进行最后的return之后再执行。
在defer归属的函数即将返回时,将延迟处理的语句按defer的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被 defer的语句,最先被执行。
package main
import "fmt"
func main() {
//延迟处理,函数关闭前执行
defer fmt.Println("执行defer语句")
for i := 0; i < 5; i++ {
fmt.Println(i)
}
}
//输出结果如下
0
1
2
3
4
执行defer语句
示例:
package main
import "fmt"
func hello() {
for i := 0; i < 10; i++ {
fmt.Println(i)
if i == 8 {
break
}
}
//延迟处理,函数关闭前执行
defer fmt.Println("执行defer")
}
func main() {
hello()
}
//运行结果为:
0
1
2
3
4
5
6
7
8
执行defer
示例:打开文件并获取内容。
package main
import (
"fmt"
"io"
"os"
)
//读取文件
func main() {
//在创建的abc.txt文件里输入内容“hello world”
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
return
}
//main函数结束前执行文件资源释放
defer file.Close()
fmt.Println("文件打开成功")
//定义参数切片
var result [128]byte
n, err := file.Read(result[:])
//文件读取完毕
if err == io.EOF {
fmt.Println("文件读取完毕", err)
return
}
//读取过程中出现异常
if err != nil {
fmt.Println("文件读取失败", err)
return
}
fmt.Printf("字节数%d个\n", n)
fmt.Printf("获取的内容是:%s\n", string(result[:]))
}
//运行结果为:
D:\goproject\src\dev_code\day25\demo3>go run main.go
文件打开成功
字节数11个
获取的内容是:hello world
示例:当读取的文件内容变成长篇文档时,该怎么办?
使用bufio读取,bufio 在 file 的基础上封装了一层API,支持更多的功能。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
//bufio读取文件
func main() {
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
return
}
defer file.Close()
//bufio缓冲区读取数据
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n')
if err == io.EOF {
fmt.Print(str)
return
}
if err != nil {
fmt.Println("文件读取失败", err)
return
}
fmt.Print(str)
}
}
//运行结果为:
D:\goproject\src\dev_code\day25\demo4>go run main.go
《生于忧患死于安乐》
舜发于畎亩之中,傅说举于版筑之间,胶鬲举于鱼盐之中,管夷吾举于士,孙叔敖举于海,百里奚举于市。故天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。
人恒过,然后能改,困于心,衡于虑,而后作;征于色,发于声,而后喻。入则无法家拂士,出则无敌国外患者,国恒亡,然后知生于忧患而死于安乐也。
作者:孟子
示例:ioutil便捷方式读取文件。
package main
import (
"fmt"
"io/ioutil"
)
//ioutil方式读取文件内容
func ReaderFile(path string) {
content, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println("文件读取异常")
return
}
fmt.Println(string(content)) //转换string格式并输出
}
func main() {
ReaderFile("./abc.txt")
}
//运行结果为:
D:\goproject\src\dev_code\day25\demo5>go run main.go
zhangsan
lisi
12345
abc123
abc456
示例:读取奇偶行内容。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
//读取文件
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
return
}
//main函数结束前执行文件资源释放
defer file.Close()
//bufio缓冲区读取
reader := bufio.NewReader(file)
//计数奇偶行
count := 0
for {
str, _, err := reader.ReadLine()
count++
if err == io.EOF {
// fmt.Println("文件读取完毕")
return
}
if err != nil {
fmt.Println("文件读取异常", err)
return
}
if count%2 == 1 {
fmt.Println(string(str))
}
}
}
//运行结果为:
D:\goproject\src\dev_code\day25\demo6>go run main.go
zhangsan
12345
abc456
示例:登录并判断用户名是否存在。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
//读取文件
func main() {
//var doing bool
var name string
fmt.Print("请输入用户名:")
fmt.Scan(&name)
//defer fmt.Println("用户不存在")
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
return
}
//main函数结束前,执行文件资源释放
defer file.Close()
//利用bufio缓冲区读取文件
reader := bufio.NewReader(file) //建立缓冲区,将文件内容放入到缓冲区
//计数奇偶行
a := 0
for {
str, _, err := reader.ReadLine()
//每次读取,a+1
a++
if err == io.EOF {
fmt.Println("文件读取完毕")
//如果文件读取完,也没有返回,则说明用户不存在
fmt.Println("用户不存在")
return
}
if err != nil {
fmt.Println("文件读取错误")
return
}
if a%2 == 1 {
if name == string(str) {
fmt.Println("登录成功")
return
}
}
}
}
//运行结果为:
D:\goproject\src\dev_code\day25\demo7>go run main.go
请输入用户名:zhangsan
登录成功
3、写入文件
os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能。
func OpenFile(name string,flag int,perm FileMode)(*File,error) {
...
}
name:要打开的文件名
flag:打开文件的模式
模式种类:
模式 | 含义 |
---|---|
os.O_WRONLY | 只写 |
os.O_CREATE | 创建文件 |
os.O_RDONLY | 只读 |
os.O_RDWR | 读写 |
os.O_TRUNC | 清空 |
os.O_APPEND | 追加 |
perm:文件权限,一个八进制数。r(读)04,W(写)02,x(执行)01。
示例:Write 和 WriteString 方式写入。
package main
import (
"fmt"
"os"
)
//使用write和writestring写入
func main() {
//写入方式打开文件,创建新文件,开启只写模式,文件权限644
file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("文件打开失败", err)
return
}
//字节切片写入
file.Write([]byte("this is byte write\n"))
//字符串写入
str := "this is string write"
file.WriteString(str)
}
//运行结果为:
执行完命令后在当前目录下出现一个abc.txt文件
D:\goproject\src\dev_code\day25\demo8>go run main.go
里面内容如下:
this is byte write
this is string write
示例:bufio.NewWriter 方式写入。
package main
import (
"bufio"
"fmt"
"os"
)
//bufio写入
func main() {
file, err := os.OpenFile("tmp.txt", os.O_CREATE|os.O_WRONLY, 0666) //WRONLY,清空
if err != nil {
fmt.Println("文件打开失败", err)
return
}
defer file.Close()
//文件写入缓冲区
write := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
//内容写入缓冲区
write.WriteString("this is bufio write\n")
}
//缓冲区数据提交写入文件
write.Flush()
}
//运行结果为:
执行完此命令后会出现一个tmp.txt文件
D:\goproject\src\dev_code\day25\demo9>go run main.go
里面内容如下:
this is bufio write
this is bufio write
this is bufio write
this is bufio write
this is bufio write
示例:ioutil.WriteFile 方式写入。
package main
import (
"fmt"
"io/ioutil"
)
func main() {
str := "this is ioutil write\nthis is test content"
//iotuil方式直接写入,字符串转换成字节数组写入
err := ioutil.WriteFile("./tmp.txt", []byte(str), 0666)
if err != nil {
fmt.Println("文件写入失败", err)
return
}
}
//运行结果为:
执行此命令,出现一个tmp.txt的文件
D:\goproject\src\dev_code\day25\demo10>go run main.go
内容如下:
this is ioutil write
this is test content