Go语言学习22-文件操作——开关读
作者:互联网
0x00 文件操作
在Go语言中,任何的文件读取或者写入,都是先打开文件——注册(defer)关闭文件
然后再读写操作
0x01 基本的方式打开文件以及读文件
用到了os包中的Open函数。Open函数打开的文件,会返回两个值,一个为错误err,一个为文件类型的指针。
读文件
使用的就是打开文件后,返回的一个文件类型的指针的Read方法。可以看到Read方法里面的参数为[]byte
类型,即byte切片。
那么我指定切片长度后,初始化即可。
当然,初始化的方式有很多种,最常用的两种就是:
var tmp = make([]byte,128)
还有一种就是:
var tmp = [128]byte //定义一个数组
fileObj.Read(tmp[:]) //从数组中创建切片,即从数组切出所有的切片
package main
import (
"fmt"
"os"
)
func main() {
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("sorry , the file opening is wrong!", err)
return
}
// fmt.Println(fileobj)
//记得关闭文件
defer fileobj.Close()
//读文件
// var tmp = make([]byte,128)
var tmp [128]byte
n, err := fileobj.Read(tmp[:])
if err != nil {
fmt.Printf("read from file failed!,err%v\n", err)
return
}
fmt.Printf("读了%d个字节!\n", n)
fmt.Println(string(tmp[:n])) //左边开头到右边为n的
}
上面这段代码,可以看到这里并没有读完,仅仅读到了128个字节而已。那么怎么办呢?加个for循环即可。可以看到第20行添加了一个for关键词。再加一个if判断,也就是当n等于0的时候,就会结束读取文件内容,直接return跳出函数。
package main
import (
"fmt"
"os"
)
func main() {
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("sorry , the file opening is wrong!", err)
return
}
// fmt.Println(fileobj)
//记得关闭文件
defer fileobj.Close()
//读文件
// var tmp = make([]byte,128)
var tmp [128]byte
for {
n, err := fileobj.Read(tmp[:])
if err != nil {
fmt.Printf("read from file failed!,err%v\n", err)
return
}
fmt.Printf("读了%d个字节!\n", n)
fmt.Println(string(tmp[:n])) //左边开头到右边为n的
if n == 0 {
return
}
}
}
虽然可以读出来,但是有一个报错。这是为什么呢?这个报错其实很简单,就是EOF而已,EOF代表的意思为:end of file
!!!
还能怎么改进呢?其实改一下n的值即可
var tmp [128]byte
for {
n, err := fileobj.Read(tmp[:])
if err != nil {
fmt.Printf("read from file failed!,err%v\n", err)
return
}
fmt.Printf("读了%d个字节!\n", n)
fmt.Println(string(tmp[:n])) //左边开头到右边为n的
if n < 128 { // 小于128就可以出现一个情况,因为每次都是读128个字节,一旦比128少,就说明读完了,就这么多。
return
}
}
0x02 bufio读文件
buf——>buffer缓冲区,就是先将读取的文件放入缓冲区,然后再进行读取。
func readFromFile2() {
//利用bufio读取文件
//前面还是一样的,先打开文件,然后再读取内容
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("err:", err)
return
}
defer fileobj.Close()
//创建一个用来从文件中读内容的对象
reader := bufio.NewReader(fileobj)
for {
//for循环里面的内容,就是依次向下读取一行文本内容
line, err := reader.ReadString('\n')
if err == io.EOF {
return
}
if err != nil {
fmt.Println("err", err)
return
}
fmt.Println(line)
}
}
但是有没有注意到,我打印出来的内容都是一行隔着一行的?是因为我用到的是fmt.Println
,没输出一次换一行。
所以改成fmt.Print
即可。
0x03 第三种读取文件——利用ioutil包
十分简单,看代码就会了
func readFromFile3() {
file, err := ioutil.ReadFile("./main.go")
if err != nil {
fmt.Println("err:", err)
return
}
fmt.Println("file:", string(file))
}
ioutil包解析
可以看到,其实就是封装了一个函数,前面都是我们熟悉的:先打开文件,然后注册defer关闭文件,后面才开始逐渐不一样开来。
总结
三种读取文件的方法各自特点:
1、如果想要自定义读取多少字节,多少内容,使用第一种方法,即fileobj.Read()
方法。
2、如果想要实现一行一行读取代码,就使用第二种方法。
3、如果想要一次性读完,就使用第三种即可,第三种读起来十分方便。
三种读取文件的代码总结
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)
func readFromFile1() {
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("sorry , the file opening is wrong!", err)
return
}
// fmt.Println(fileobj)
//记得关闭文件
defer fileobj.Close()
//读文件
// var tmp = make([]byte,128)
var tmp [128]byte
for {
n, err := fileobj.Read(tmp[:])
if err != nil {
fmt.Printf("read from file failed!,err%v\n", err)
return
}
fmt.Printf("读了%d个字节!\n", n)
fmt.Println(string(tmp[:n])) //左边开头到右边为n的
if n < 128 {
return
}
}
}
func readFromFile2() {
//利用bufio读取文件
//前面还是一样的,先打开文件,然后再读取内容
fileobj, err := os.Open("./main.go")
if err != nil {
fmt.Println("err:", err)
return
}
defer fileobj.Close()
//创建一个用来从文件中读内容的对象
reader := bufio.NewReader(fileobj)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
return
}
if err != nil {
fmt.Println("err", err)
return
}
fmt.Println(line)
}
}
func readFromFile3() {
file, err := ioutil.ReadFile("./main.go")
if err != nil {
fmt.Println("err:", err)
return
}
fmt.Println("file:", string(file))
}
func main() {
readFromFile1()
readFromFile2()
readFromFile3()
}
标签:Println,tmp,return,22,err,fmt,开关,fileobj,Go 来源: https://www.cnblogs.com/sukusec301/p/15956949.html