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

一、文件处理概述

基本所有语言都支持一些文件资源的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标准包

  • os包

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

  • io包

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

  • io/ioutil包

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

  • bufio包

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)
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容