Go基础系列随笔-生活工作点滴

20 Go 文件IO (一):文件操作

2019-07-07  本文已影响5人  GoFuncChan

一、文件处理概述

基本所有语言都支持一些文件资源的IO操作,所谓IO即对资源的读写。在类Unix的设计哲学中,一切资源皆为文件。在IO中你会常见到一些Write、Read、Writer、Reader的概念,有时你会对一些读写主体产生混淆,这里可以明晰一下:

一般读写的主体都为运行的程序,程序运行于内存中,而资源一般位于程序主体的外部,多以Read一般理解为读入,将外部资源读入程序内存,而Write则相反,指数据有程序内存写出到外部的磁盘资源。当然所谓外部不一定指磁盘,这里的外部是相对程序主体而言的。而Reader、Writer就好理解了,它们是抽象化的读写操作主体,如Read操作是通过Reader实现的,Reader内部提供Read方法。另外,IO操作的数据单位一般都为byte,你会看到go的标准库中,许多数据IO都是通过[]byte传输的。

理清以上比较容易混淆的概念再去阅读Go的IO相关包源码就好理解了。

二、Go IO标准包

一个平台无关的操作系统接口,提供一些系统资源的调用功能,如文件、目录打开关闭,环境设置、状态信息等。

提供了对I/O原语的基本接口。本包的基本任务是包装这些原语已有的实现(如os包里的原语),使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加了一些相关的原语的操作。与os包配合,所谓io就是一些读写的操作。

基于io包实现一些实用的工具函数,由于封装性较好,使用简单,所以日常开发该包使用多一些。

bufio包实现了有缓冲的I/O。它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象。如操作的资源较大,一般建议使用带缓冲的bufio。

三、文件操作演示

1.基本文件读写

示例一:打开一个文件简单操作,打开后延时关闭。

func BaseFileOperation01() {
    file, err := os.Open("/path/to/file_operation_demo_text.txt")
    if err != nil {
        fmt.Println("文件打开错误,err=", err)
        return
    }

    //完成后延时1s关闭
    defer func() {
        time.Sleep(time.Second)
        file.Close()
    }()
    info, _ := file.Stat()

    fmt.Println(info.Name())
}

示例二:以只读方式打开一个文件创建缓冲读取器,逐行读到末尾。

func BaseFileOperation02() {
    file, err := os.OpenFile("/path/to/file_operation_demo_text.txt", os.O_RDONLY, 0666)
    if err != nil {
        fmt.Println("文件打开错误,err=", err)
        return
    }
    defer file.Close() //完成后关闭

    //创建缓冲读取器
    reader := bufio.NewReader(file)
    for {
        readString, err := reader.ReadString('\n') //以换行符为间隔分箱读取
        if err != nil {
            if e == io.EOF {
                break
            }

            fmt.Println("缓冲读取错误,err=", err)
            return
        }

        fmt.Println(readString)
    }

    fmt.Println("缓冲读取文件完成")
}

示例三:使用ioutil包对文件进行简易读取

func BaseFileOperation03() {
    bytes, err := ioutil.ReadFile("/path/to/file_operation_demo_text.txt")
    if err != nil {
        fmt.Println("文件打开错误,err=", err)
        return
    }

    fmt.Println(string(bytes))
}

示例四:以创写追加或创写覆盖方式打开一个文件,缓冲式写出几行数据,倒干缓冲区后退出

func BaseFileOperation04() {
    openFile, err := os.OpenFile("/path/to/file_operation_demo_text111.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if e != nil {
        fmt.Println("文件打开错误,err=", err)
        return
    }
    defer openFile.Close()

    //创建一个缓冲桶
    writer := bufio.NewWriter(openFile)
    writer.WriteString("这是新插入的信息1\n")
    writer.WriteString("这是新插入的信息2\n")
    writer.WriteString("这是新插入的信息3\n")
    writer.WriteString("这是新插入的信息4\n")

    flush := writer.Flush()

    fmt.Println("缓冲写入数据完成!!!清空缓冲状态:", flush)
}

示例五:使用os包的状态检测结合os.IsNotExist(err)判断文件是否存在。

func BaseFileOperation05() {
    _, err := os.Open("/path/to/file_operation_demo_text11.txt")
    exist1 := os.IsNotExist(err)
    fmt.Println("文件是否不存在:", exist1)

    exist2 := os.IsExist(err)
    fmt.Println("文件是否存在:", exist2)
}

示例六:使用ioutil包进行建议文件写出。

func BaseFileOperation06() {
    //
    stringByte := []byte("这是一次用ioutil包的简易写出操作\n")
    ioutil.WriteFile("/path/to/file_operation_demo_text111.txt", stringByte, 0666)

    fmt.Println("简易写出完成!")

}

2.文件拷贝

示例七:ioutil包简单拷贝

func BaseFileOperation07() {
    bytes, err := ioutil.ReadFile("/path/to/file_operation_demo_text111.txt")
    if e != nil {
        fmt.Println("文件读取错误,err=", err)
        return
    }

    err = ioutil.WriteFile("/path/to/file_operation_demo_text222.txt", bytes, 0666)
    if err != nil {
        fmt.Println("文件写入错误,err=", err)
        return
    }

    fmt.Println("文件拷贝完成!!!")
}

示例八:io.Copy进行文件拷贝

func BaseFileOperation08() {
    //只读模式打开文件
    src, err := os.OpenFile("/path/to/file_operation_demo_text.txt", os.O_RDONLY, 0666)
    if err != nil {
        fmt.Println("文件打开错误,err=", err)
        return
    }
    defer src.Close()

    //只写模式打开创建文件
    dst, err := os.OpenFile("/Users/fun/Code/mygo/src/mydemo/text/file_operation_demo_text_copy.txt", os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("文件写入错误,err=", err)
        return
    }
    defer dst.Close()

    written, err := io.Copy(dst, src)
    if err != nil {
        fmt.Println("ioutil拷贝操作错误!!!")
        return
    }

    fmt.Println("ioutil拷贝操作完成:", written)
}

示例九:使用缓冲1K的缓冲区配合缓冲读写器进行图片拷贝

func BaseFileOperation09() {
    src, err := os.OpenFile("/path/to/myimage.jpg", os.O_RDONLY, 0666)
    if err != nil {
        fmt.Println("文件打开错误,err=", err)
        return
    }
    defer src.Close()

    //只写模式打开创建文件
    dst, err := os.OpenFile("/path/to/myimage_copy.jpg", os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        fmt.Println("文件写入错误,err=", err)
        return
    }
    defer dst.Close()

    //创建缓冲区[[byte
    var n int = 0
    bufbytes := make([]byte, 1024)
    reader := bufio.NewReader(src)
    writer := bufio.NewWriter(dst)

    for {
        n++
        _, err = reader.Read(bufbytes)
        if err != nil {
            if err == io.EOF {
                fmt.Println("文件读到末尾!", n)
                break
            }
            fmt.Println("读取图片到缓冲区错误:", err)
        }

        _, err = writer.Write(bufbytes)
        if err != nil {
            fmt.Println("读取图片到缓冲区错误:", err)
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读