Go 语言文件操作:读取文件 1 个改进

使用Go读取文件的常见办法

在学习C语言的时候,对文件的读写操作,都应该获取到相应的文件操作句柄;但是在Go里面,官方提供的标准包可能帮我们屏蔽了一些细节,让我们能一次性将文件内容读取出来;具体使用哪种,笔者认为这应该由我们的业务场景来决定;但我们要清楚有这些个办法能做文件的读取操作。

用来演示的文件test.txt

hello world!
this is to test file reading
...

1 使用os包

使用流程先打开文件,获取到文件操作句柄,打开文件操作可以用os.Open, os.OpenFile,这里的例子笔者用os.Open,其实际调用的也是os.OpenFile

示例代码

func main() {

    fileContent, err := fileReadDemo1("./test.txt")
    if nil != err {
        fmt.Println(err)
        return
    }

    fmt.Println(string(fileContent))

}

func fileReadDemo1(p string) ([]byte, error) {
    //打开文件p,获取p的文件操作句柄,文件不存在则panic
    fileHandler, err := os.Open(p)
    if nil != err {
        panic(err)
    }
    //关闭文件
    defer fileHandler.Close()

    //分配1k的buffer,具体应该分配多少,可以具体考量
    buffer := make([]byte, 1024)
    //要返回的数据
    ret := []byte{}
    //循环读取
    for {
        readLength, err := fileHandler.Read(buffer)
        if err != nil {
            //文件结尾
            if err == io.EOF {
                ret = append(ret, buffer[:readLength]...)
                return ret, nil
            }

            return nil, err
        }
        ret = append(ret, buffer[:readLength]...)
    }

}

运行结果

PS D:\GoPractice\fileOpt> go run .\main.go
hello world!
this is to test file reading
...

2 结合os和bufio,实现选择性读取

打开文件的操作还是一样的,但是我们用bufio来实例化一个ReadBuffer,这样我们就可以使用ReadBuffer所绑定的方法,达到不同方式读取文件的操作

示例代码

func main() {

    fileReadDemo2("./test.txt")

}

func fileReadDemo2(p string) {
    fileHandler, err := os.Open(p)
    checkErr(err)

    fileReader := bufio.NewReader(fileHandler)

    //ReadLine
    oneLine, _, err := fileReader.ReadLine()
    checkErr(err)
    fmt.Println("这是文件", p, "的一行:", string(oneLine))

    //ReadByte
    oneByte, err := fileReader.ReadByte()
    checkErr(err)
    fmt.Println("这是继", string(oneLine), "之后", "文件", p, "的一个byte:", oneByte)

    //ReadBytes
    readBytes, err := fileReader.ReadBytes('\n')
    checkErr(err)
    fmt.Println(string(readBytes))
}

//由于出现许多需要判断error的地方,且都是直接panic,就写了一个checkErr
func checkErr(err  error) {
    if nil != err {
         panic(err)
    }
}

运行结果

PS D:\GoPractice\fileOpt> go run .\main.go
这是文件 ./test.txt 的一行: hello world!
这是继 hello world! 之后 文件 ./test.txt 的一个byte: 116
his is to test file reading

3 使用ioutil包

当文件比较小的时候,且我们就是知道我们要读取文件的全部数据后再进行处理,我们可以选择使用ioutil.ReadFile来读取文件,当然,我们可以再使用os.Open获取到操作句柄的时候,使用ioutil.ReadAll来读取,这里我们示例用ioutil.ReadFile

示例代码

func main() {
    bs, err := ioutil.ReadFile("./test.txt")
    checkErr(err)
    fmt.Println(string(bs), err)
}
func checkErr(err error) {
 if nil != err {
     panic(err)
    }
}

4 使用io包

使用io.ReadFull,这个笔者也不经常用,这里给出一个demo了解一下

示例代码

func main() {
    fi, err := os.Stat("./test.txt")
    checkErr(err)
    buffer := make([]byte, fi.Size())
    // buffer := []byte{}
    fileHandler, err := os.Open("./test.txt")
    checkErr(err)
    //如果len(buffer)>文件大小,则会报错
    n, err := io.ReadFull(fileHandler, buffer)
    checkErr(err)
    fmt.Println(string(buffer[:n]))
}

运行结果

PS D:\GoPractice\fileOpt> go run .\main.go
hello world!
this is to test file reading
...

参考:studygolang.com/pkgdoc

本文为 Wiki 文章,邀您参与纠错、纰漏和优化
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!