20-Go语言文件操作

Go语言操作文件

文件的打开与关闭
  • 文件的打开
    • 在Go语言的os包中提供了一个函数, 叫做Open, 就是专门用于打开某一个文件的
    • 注意点:
      如果文件不存在不会自动创建,通过open函数打开的文件只能读取, 不能写入
  • 文件的关闭
    • 在Go语言的os包中提供了一个函数, 叫做Close, 就是专门用于关闭某个打开文件的
package main

import (
    "fmt"
    "os"
)

func main() {
    /*
    1.如何打开文件?
    在Go语言的os包中提供了一个函数, 叫做Open, 就是专门用于打开某一个文件的
    注意点:
    如果文件不存在不会自动创建
    通过open函数打开的文件只能读取, 不能写入

    2.如何关闭文件?
    在Go语言的os包中提供了一个函数, 叫做Close, 就是专门用于关闭某个打开文件的
    */

    //打开文件

    //func Open(name string) (*File, error)
    fp, err := os.Open("D:/wjh.txt")
    if err != nil {
        fmt.Println("打开文件失败")
    }else {
        fmt.Println(fp)
    }

    //关闭文件
    defer func() {
        if err = fp.Close(); err != nil {
            fmt.Println("文件关闭失败")
        }else {
            fmt.Println("文件关闭成功")
        }
    }()
}

文件的读取操作
  • 通过os包中的Read函数读取
  • 注意点:
    Read函数会将读取到的数据放到指定的切片中, 并且会一次性将所有的数据都读取进来会将读取到的byte个数返回给我们, 并且还会返回一个error,
    如果读取成功, 那么error等于nil, 如果读取失败那么error就不等于nil
package main

import (
    "fmt"
    "os"
)

func main() {
    /*
    第一种读取的方式:
    通过os包中的Read函数读取
    func (f *File) Read(b []byte) (n int, err error)
    Read函数会将读取到的数据放到指定的切片中, 并且会一次性将所有的数据都读取进来
    会将读取到的byte个数返回给我们, 并且还会返回一个error,
    如果读取成功, 那么error等于nil, 如果读取失败那么error就不等于nil
     */

    //打开一个文件
    fp, err := os.Open("D:/wjh.txt")
    if err != nil {
        fmt.Println("打开文件失败")
    } else {
        fmt.Println("打开文件成功")
    }

    //关闭文件
    defer func() {
        if err = fp.Close();err != nil {
            fmt.Println("关闭文件失败")
        }
    }()

    //读取文件内容
    // read函数接收一个切片, 会将读取到的数据放到指定的切片中
    // 注意点: 会一次性将文件中的数据全部读取进来

    //定义一个切片保存读取的数据
    sce := make([]byte,7)
    for  {
        len, err := fp.Read(sce)
        if err != nil || len <= 0 {
            break
        }
        fmt.Print(string(sce[: len]))
    }
}
  • 带缓冲区读取数据
    • 注意点:当文件较大时,为了提高效率建议使用带缓冲区方式读取
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    /*
    第一种读取的方式:
    通过bufio包中的ReadBytes和ReadString函数
    func (b *Reader) ReadBytes(delim byte) (line []byte, err error)
     */

    //打开文件
    fp, err := os.Open("D:/wjh.txt")
    if err != nil {
        fmt.Println("打开文件失败")
    }

    //关闭文件
    defer func() {
        if err = fp.Close(); err != nil {
            fmt.Println("关闭文件失败")
        }
    }()

    //创建缓冲区
    // 将打开的文件句柄传递给NewReader函数, 会返回一个新的句柄
    // 缓冲区默认的大小是4096
    r := bufio.NewReader(fp)

    // 利用缓冲区的句柄来读取数据
    // 接收一个参数, 这个参数用于告诉ReadBytes函数, 读取到什么地方接收
    // 会将读取到的数据放到一个切片中返回给我们

    /*
    注意点:
    abcdefg\n
    1234567
    第一次读取: buf = abcdefg\n
    第二次读取: buf = 1234567
    但是由于第二次读取一直读到了文件的末尾都没有读到\n, 所以ReadBytes函数就给err赋值了一个io.EOF
    所以如果1234567后面没有\n, 并且是先判断错误, 那么就会少输出一次
     */

    /*for {
        buff, err := r.ReadBytes('\n')
        fmt.Print(string(buff))
        if err == io.EOF {
            break
        }
    }*/

    for {
        str, err := r.ReadString('\n')
        fmt.Print(str)
        if err == io.EOF {
            break
        }
    }

}
  • 通过ioutil包中的ReadFile函数读取
    • func ReadFile(filename string) ([]byte, error)
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    /*
    第三种读取的方式:
    通过ioutil包中的ReadFile函数读取
    func ReadFile(filename string) ([]byte, error)
     */

    // 会将指定路径中的文件一次性读取进来
    // 接收一个参数: 用于传递需要读取的文件路径
    // 返回两个值:
    // 第一个返回值: 读取到的数据
    // 第二个返回值: 读取失败就不等于nil
    buff, err := ioutil.ReadFile("D:/wjh.txt")
    if err != nil {
        fmt.Println("读取文件失败")
    } else {
        fmt.Println(string(buff))
    }
}

文件写入操作
  • 通过os包中的Write函数一次性写入
    • 注意点: Open函数打开的文件只能读取, 不能写入
      Create函数的作用: 创建一个文件
      文件不存在, 会自动创建一个新的
      文件存在, 会覆盖以前的(相当于创建了一个新的替换掉了以前的旧的)
package main

import (
    "fmt"
    "os"
)

func main() {
    /*
    第一种写入的方式:
    通过os包中的Write函数写入
     */

    //1.打开一个文件

    // 注意点: Open函数打开的文件只能读取, 不能写入
    // Create函数的作用: 创建一个文件
    // 注意点: 文件不存在, 会自动创建一个新的
    //         文件存在, 会覆盖以前的(相当于创建了一个新的替换掉了以前的旧的)
    //func Create(name string) (file *File, err error)

    fp, err := os.Create("D:/lnj.txt")
    if err != nil {
        fmt.Println("打开文件失败")
    }

    //2.关闭文件
    defer func() {
        if err = fp.Close();err != nil {
            fmt.Println("关闭文件失败")
        }
    }()

    //3.写入文件内容
    //func (f *File) Write(b []byte) (n int, err error)
    // 特点: 会将指定的数据一次性写入到文件中
    // 所以不适合数据量比较大的情况
    buf := []byte{'w','j','h','\r','\n'}
    len, err := fp.Write(buf)
    if err != nil {
        fmt.Println("写入失败")
    }else {
        fmt.Print("写入了", len,"字节")
    }
}
  • 通过bufio包中的Write和WirteString函数写入(带缓冲区的方式)
package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    /*
    第二种写入的方式:
    通过bufio包中的Write和WirteString函数写入
     */

    //创建一个文件
    fp, err := os.Create("D:/lnj.txt")
    if err != nil {
        fmt.Println("创建文件失败")
    }

    //关闭文件
    defer func() {
        if err = fp.Close(); err != nil {
            fmt.Println("关闭文件失败")
        }
    }()

    //1.创建一个写入缓冲区
    //func NewWriter(w io.Writer) *Writer
    w := bufio.NewWriter(fp)

    //2.写入数据
    /*//func (b *Writer) Write(p []byte) (nn int, err error)
    //写入的内容
    sce := []byte{'w','j','h','\r','\n'}
    len, err := w.Write(sce)

    if err != nil {
        fmt.Println("写入文件失败")
    }else {
        fmt.Println("写入了",len,"字节的数据")
    }
    */

    //使用WriteString函数写入内容
    //func (b *Writer) WriteString(s string) (int, error)

    len, err := w.WriteString("www.it666.com\r\n")
    if err != nil {
        fmt.Println("写入数据失败")
    }else {
        fmt.Println("写入了",len,"字节")
    }

    //注意点:
    // 如果通过带缓冲区的方式写入数据, 那么必须在写入完毕之后刷新一下缓冲区, 才会将缓冲区中的数据真正的写入到文件中
    w.Flush()
}
  • 通过ioutil包中WirteFile函数写入
    • func WriteFile(filename string, data []byte, perm os.FileMode) error
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    /*
    第三种写入的方式:
    通过ioutil包中WirteFile函数写入
    func WriteFile(filename string, data []byte, perm os.FileMode) error
    */

    buf := []byte{'w','j','h','\r','\n'}
    err := ioutil.WriteFile("D:/wjh.txt", buf, 0666)
    if err != nil {
        fmt.Println("写入数据失败")
    }else {
        fmt.Println("写入数据成功")
    }
}

文件追加数据操作
  • 通过os包中的另一个函数: OpenFile
    • func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
    • 作用: 打开一个文件, 并且文件不存在可以创建(注意是可以不是自动)
      • 第一个参数: 需要打开文件的路径
      • 第二个参数: 以什么模式打开文件 (只读/只写/可读可写/追加/)模式可以同时指定多个, 多个之间使用|分隔, 例如 O_CREATE | O_WRONLY
      const (
          O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
          O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
          O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
          O_APPEND int = syscall.O_APPEND // 写操作时将数据附加文件尾部
          O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
          O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用, 文件必须不存在
          O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
          O_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
      )
      
      • 第三个参数: 指定文件的权限, 只对Linux系统有效, 在Windows下无效
        • 0.没有任何权限
        • 1.执行权限(如果是可执行程序, 可以运行)
        • 2.写权限
        • 3.写权限和执行权限
        • 4.读权限
        • 5.读权限和执行权限
        • 6.读权限和写权限
        • 7.读权限和写权限以及执行权限
        • 一般情况下写 0666
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    /*
    os包中的Open函数只能读取不能写入
    os包中的Create函数可以读取也可以写入, 但是每次执行都会覆盖原有的文件, 每次执行都是一个空文件
    所以: 如果想要往文件中追加数据, 利用如上两个方法是不行的
    所以: 需要通过os包中的另一个函数: OpenFile

    作用: 打开一个文件, 并且文件不存在可以创建(注意是可以不是自动)
    第一个参数: 需要打开文件的路径
    第二个参数: 以什么模式打开文件 (只读/只写/可读可写/追加/)
                模式可以同时指定多个, 多个之间使用|分隔, 例如 O_CREATE | O_WRONLY
    第三个参数: 指定文件的权限, 只对Linux系统有效, 在Windows下无效

    func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

    const (
        O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
        O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
        O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
        O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
        O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
        O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,文件必须不存在
        O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
        O_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
    )

    0.没有任何权限
    1.执行权限(如果是可执行程序, 可以运行)
    2.写权限
    3.写权限和执行权限
    4.读权限
    5.读权限和执行权限
    6.读权限和写权限
    7.读权限和写权限以及执行权限
    一般情况下写 0666

    注意点: OpenFile和Open函数一样, 打开文件之后需要手动关闭文件
     */

    //1.打开一个文件
    fp, err := os.OpenFile("D:/lnj.txt", os.O_CREATE|os.O_RDWR |os.O_APPEND, 0666)
    if err != nil {
        fmt.Println("创建文件失败")
    }

    //关闭文件
    defer func() {
        if err = fp.Close(); err != nil {
            fmt.Println("关闭文件失败")
        }
    }()

    //一次性写入数据到文件
    len, err := fp.WriteString("www.it666.com\r\n")
    if err != nil {
        fmt.Println("写入数据失败")
    }else {
        fmt.Println("写入了",len,"字节的数据")
    }

    //一次性读取所有数据
    //注意点: 不能读写一起操作,否则会读取数据失败
    //创建切片保存读取数据
    buf := make([]byte, 1024)
    //读取文件中的数据
    length, err := fp.Read(buf)
    if err != nil {
        fmt.Println("读取文件失败")
    }else {
        fmt.Println(string(buf[: length]))
    }


    //使用缓冲区写入追加数据
    //创建写入缓冲区
    w := bufio.NewWriter(fp)
    //写入数据
    len, err := w.WriteString("我是小老虎\r\n")
    if err != nil {
        fmt.Println("写入数据失败")
    }else {
        fmt.Println("写入了",len,"字节的数据")
    }
    //刷新缓冲区数据
    w.Flush()

    //使用缓冲区读取数据
    //创建读取的缓冲区
    r := bufio.NewReader(fp)
    //读取数据
    for{
        str, err := r.ReadString('\n')
        fmt.Print(str)
        if err == io.EOF {
            break
        }
    }
}

获取文件信息
  • os包中Stat函数用来获取文件的信息
    • func Stat(name string) (fi FileInfo, err error)
package main

import (
    "fmt"
    "os"
)

func main() {
    info,err := os.Stat("D:/lnj.txt")
    if err != nil {
        fmt.Println(err)
    }else {
        fmt.Println(info.Name()) //文件名称
        fmt.Println(info.Size()) //文件大小
        fmt.Println(info.ModTime()) //文件修改时间
        fmt.Println(info.IsDir()) //是否为目录
    }
}

利用缓冲区方式拷贝文件
package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    //拷贝一张照片
    //文件较大,使用带缓冲区方式拷贝文件
    //读取文件
    //1.打开文件
    rp, err := os.Open("D:/20150705_IMG_0024.JPG")
    if err != nil {
        fmt.Println("打开文件失败")
    }
    //2.关闭文件
    defer func() {
        if err = rp.Close(); err != nil{
            fmt.Println("关闭文件失败")
        }
    }()

    //写入文件
    //1.创建文件
    wp, err := os.Create("D:/hui.jpg")
    if err != nil {
        fmt.Println("创建文件失败")
    }

    //2.关闭文件
    defer func() {
        if err = wp.Close(); err != nil {
            fmt.Println("关闭文件失败")
        }
    }()

    //创建读取缓冲区
    r := bufio.NewReader(rp)
    //创建写入缓冲区
    w := bufio.NewWriter(wp)

    //利用io包中的copy函数进行文件拷贝
    //func CopyN(dst Writer, src Reader, n int64) (written int64, err error)

    len, err := io.Copy(w,r)
    if err != nil {
        fmt.Println("拷贝文件失败")
    }else {
        fmt.Println("拷贝了",len,"字节的数据")
    }
}

遍历目录操作
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    //遍历文件夹中的文件,将遍历到的所有文件的路径保存到切片中
    //func ReadDir(dirname string) ([]os.FileInfo, error)

    sce := listDir("D:/demo")
    fmt.Println(sce)

}

func listDir(path string) (sce []string) {
    //1.读取指定的目录
    dir, err := ioutil.ReadDir(path)
    if err != nil {
        fmt.Println("读取目录失败")
    } else {
        //2.遍历文件信息
        for _, value := range dir {
            //3.判断是否为目录
            if value.IsDir() {
                //再次遍历子目录
                sce1 := listDir(path + "/" + value.Name())
                for _, v := range sce1 {
                    sce = append(sce, v)
                }
                //是文件存储在切片中
            }else {
                sce = append(sce, path + "/" + value.Name())
            }
        }
    }
    return
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352