目录
GO文件流
计算机中的文件是存储在外部介质(硬盘)上的数据集合,文件分为文本文件和二进制文件。
打开和关闭文件
os.open()函数能够打开一个文件,返回一个*File和一个err,对得到的文件示例close()方法能够关闭文件。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
} else {
fmt.Println("文件打开成功")
file.Close()
fmt.Println("文件关闭")
}
}
运行结果
D:\golang\src\day24\OSfile\demo2>go run main.go
文件打开成功
文件关闭
读取文件
接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回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 Hello() {
for i := 0; i < 10; i++ {
fmt.Println(i)
if i == 8 {
// panic("程序宕机") //手动宕机处理,立马关闭程序,释放内存
break
}
}
defer fmt.Println("defer正在执行") //延迟执行,等函数全部执行完之后在执行
}
func main() {
Hello()
}
运行结果
D:\golang\src\day24\OSfile\demo1>go run main.go
0
1
2
3
4
5
6
7
8
defer正在执行
panic手动宕机处理,立马关闭程序,释放内存
示例
package main
import "fmt"
func Hello() {
defer fmt.Println("defer正在执行") //延迟执行,等函数全部执行完之后在执行
for i := 0; i < 10; i++ {
fmt.Println(i)
if i == 8 {
panic("程序宕机") //手动宕机处理,立马关闭程序,释放内存
}
}
}
func main() {
Hello()
}
运行结果
D:\golang\src\day24\OSfile\demo1>go run main.go
0
1
2
3
4
5
6
7
8
defer正在执行
panic: 程序宕机
goroutine 1 [running]:
main.Hello()
D:/golang/src/day24/OSfile/demo1/main.go:10 +0x105
main.main()
D:/golang/src/day24/OSfile/demo1/main.go:16 +0x17
exit status 2
defer读取
package main
import (
"fmt"
"io"
"os"
)
func main() {
//file, err := os.Open("D:/golang/src/day24/bufio/demo1/a.txt")
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
return
}
//main函数结束前执行
defer file.Close()
//fmt.Println("文件打开成功")
//定义参数切片
var reslut [128]byte
for {
n, err := file.Read(reslut[:])
//文件读取完毕操作
if err == io.EOF {
fmt.Println("文件读取完成", err)
return
}
//读取过程出现异常
if err != nil {
fmt.Println("文件出现异常", err)
return
}
fmt.Println("文件字节数为:", n)
fmt.Println(string(reslut[:]))
}
}
运行结果
D:\golang\src\day24\FileRead\demo1>go run main.go
文件字节数为: 30
zhangsan
123abc
lisi
abc123
文件读取完成 EOF
假如文件长度超过128字节,会发生什么
a.txt文件
舜发于畎亩之中,傅说举于版筑之间,胶鬲举于鱼盐之中,管夷吾举于士,孙叔敖举于海,百里奚举于市。
故天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。(是人 一作:斯人)
人恒过,然后能改;困于心,衡于虑,而后作;征于色,发于声,而后喻。入则无法家拂士,出则无敌国外患者,国恒亡。然后知生于忧患而死于安乐也。
作者 : 孟子
package main
import (
"fmt"
"io"
"os"
)
func main() {
file, err := os.Open("D:/golang/src/day24/bufio/demo1/a.txt")
//file, err := os.Open("./abc.txt")
if err != nil {
fmt.Println("文件打开失败", err)
return
}
//main函数结束前执行
defer file.Close()
//fmt.Println("文件打开成功")
//定义参数切片
var reslut [128]byte
for {
_, err := file.Read(reslut[:])
//文件读取完毕操作
if err == io.EOF {
fmt.Println("文件读取完成", err)
return
}
//读取过程出现异常
if err != nil {
fmt.Println("文件出现异常", err)
return
}
//fmt.Println("文件字节数为:", n)
fmt.Println(string(reslut[:]))
}
}
运行结果
D:\golang\src\day24\FileRead\demo1>go run main.go
舜发于畎亩之中,傅说举于版筑之间,胶鬲举于鱼盐之中,管夷吾举于士,孙叔敖举于海,百里��
�举于市。
故天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其��
�为,所以动心忍性,曾益其所不能。(是人 一作:斯人)
人恒过,然后能改;困于心,衡于虑,��
�后作;征于色,发于声,而后喻。入则无法家拂士,出则无敌国外患者,国恒亡。然后知生于忧�
��而死于安乐也。
作者 : 孟子�。入则无法家拂士,出则无敌国外患者,国恒亡。然后知生于忧�
文件读取完成 EOF
Bufio
会有乱码的情况出现,此时要用到bufio缓冲
解决方法:使用bufio读取。bufio在file的基础上封装了一层API,支持更多的功能。
package main import ( "bufio" "fmt" "io" "os" ) func main() { file, err := os.Open("./a.txt") if err != nil { fmt.Println("文件打开失败", err) return } //main函数结束前执行 defer file.Close() //文件缓存区 reader := bufio.NewReader(file) for { str, err := reader.ReadString('\n') //文件读取完毕操作 if err == io.EOF { fmt.Println(str) fmt.Println("文件读取完成", err) return } //读取过程出现异常 if err != nil { fmt.Println("文件出现异常", err) return } //fmt.Println("文件字节数为:", n) fmt.Print(str) } } 运行结果 D:\golang\src\day24\bufio\demo1>go run main.go 舜发于畎亩之中,傅说举于版筑之间,胶鬲举于鱼盐之中,管夷吾举于士,孙叔敖举于海,百里奚举于市。 故天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。(是人 一作:斯人) 人恒过,然后能改;困于心,衡于虑,而后作;征于色,发于声,而后喻。入则无法家拂士,出则无敌国外患者,国恒亡。然后知生于忧患而死于安乐也。 作者 : 孟子 文件读取完成 EOF
另一种方式iouil
package main
import (
"fmt"
"io/ioutil"
)
//iouill方式读取
func Read(p string) {
const1, err := ioutil.ReadFile(p)
if err != nil {
fmt.Println("文件打开异常", err)
return
}
fmt.Println(string(const1))
}
func main() {
Read("D:/golang/src/day24/bufio/demo1/a.txt")
}
运行结果
D:\golang\src\day24\iouit>go run main.go
舜发于畎亩之中,傅说举于版筑之间,胶鬲举于鱼盐之中,管夷吾举于士,孙叔敖举于海,百里奚举于市。
故天将降大任于是人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。(是人 一作:斯人)
人恒过,然后能改;困于心,衡于虑,而后作;征于色,发于声,而后喻。入则无法家拂士,出则无敌国外患者,国恒亡。然后知生于忧患而死于安乐也。
作者 : 孟子
相比较而言bufio还是要更加灵活,比如输出奇数行或者偶数行
abc文件
zhangsan
123abc
lisi
abc123
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()
//文件缓存区
reader := bufio.NewReader(file)
count := 0
for {
str, _, err := reader.ReadLine()
count++
//文件读取完毕操作
if err == io.EOF {
// fmt.Println(str)
// fmt.Println("文件读取完成", err)
return
}
//读取过程出现异常
if err != nil {
fmt.Println("文件出现异常", err)
return
}
if count%2 == 1 {
fmt.Println(string(str))
}
//fmt.Println("文件字节数为:", n)
}
}
运行结果
D:\golang\src\day24\FileRead\demo2>go run main.go
zhangsan
lisi
写入文件
os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能。
func 0penFile(name string,flag int,perm FileHode)(*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。
示例
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("tmp.txt",os.O_CREATE|os.O_WRONLY,0755)
if err !=nil{
fmt.Println("err",err)
return
}
//最后关闭文件
defer file.Close()
//定义写入的内容
str := "hello world"
//字符串方式写入
file.Write([]byte("This is Test\n"))
//字节方式写入
file.WriteString(string(str))
}
运行结果,自动生成文件
D:\golang\src\day24\Wirt\demo1>go run main.go
This is Test
hello world
示例: bufio.NewWriter方式。
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("tmp.txt",os.O_CREATE|os.O_WRONLY,0755)
if err !=nil{
fmt.Println("err",err)
return
}
//最后关闭文件
defer file.Close()
write := bufio.NewWriter(file)
for i := 0; i < 10; i++ {
write.WriteString("hello world\n")//将数据写入缓存区
}
write.Flush()
}
生成tmp.txt如下
示例: ioutil. WriteFile方式。
package main
import (
"fmt"
"io/ ioutil”
)
func main() {
str := "hello world\nthis is test"
//字符串转换为字节数组写入
err := ioutil.WriteFile("./tmp. txt",[]byte(str), 0666)
if err != nil{
fmt . Println("文件写入错误",err)
return
}
}
在当前目录下生成tmp.txt内容如下:
hello world
this is test
判断用户是否存在
abc.txt文件内容如下
zhangsan
package main
import (
"bufio"
"fmt"
"io"
"os"
)
//读取文件
func main() {
var name string
//defer fmt.Println("用户不存在")
//控制台输入
fmt.Print("请输入用户名:")
fmt.Scan(&name)
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 {
//登录验证
if name == string(str) {
fmt.Print("用户已存在")
return
}
}
}
}
运行结果
D:\golang\src\day24\Login>go run main.go
请输入用户名:zhangsan
用户已存在
D:\golang\src\day24\Login>go run main.go
请输入用户名:abc
用户不存在