golang 文件操作

golang的文件操作在os包

读文件

1)文件的打开和关闭操作

fmt.Printf("file=%v", file)输出的是文件地址而不是文件内容
复制代码
package main

import (
    "fmt"
    "os"
)

func main() {
    //打开文件
    //file叫file对象/指针/文件句柄
    file, err := os.Open("/Users/Tsunami/Documents/config.yaml")
    if err != nil {
        fmt.Println("open file err=", err)
    }
    //输出文件
    fmt.Printf("file=%v", file)
    //关闭文件
    err = file.Close()
    if err != nil {
        fmt.Println("close file err=", err)
    }
}
复制代码

2)读取文件的内容并显示在终端(带缓冲区的方式,使用os.Open,file.Close,bufio.NewReader(),reader.ReadString函数和方法)

复制代码
package main

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

func main() {
    //打开文件
    //file叫file对象/指针/文件句柄
    file, err := os.Open("/Users/Tsunami/Documents/hello.txt")
    if err != nil {
        fmt.Println("open file err=", err)
    }
    //当函数退出时,要及时的关闭文件
    defer file.Close()
    //创建一个*Reader,是带缓冲的
    /*
        const (
        defaultBufsize = 4096 //默认缓冲区为4096
        )
    */
    reader := bufio.NewReader(file)
    //循环读取文件内容
    for {
        str, err := reader.ReadString('\n') //读到一个换行符就结束
        if err == io.EOF {                  //io.EOF表示文件的末尾
            break
        }
        //输出内容
        fmt.Print(str)
    }
    fmt.Println("文件读取结束。。。")
}
复制代码

3)读取文件的内容并显示在终端(使用ioutil一次将整个文件读入到内存中),这种方法适用于文件不大的情况。相关方法和函数(ioutil.ReadFile)

复制代码
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    //使用ioutil.ReadFile一次性将文件读取
    file := "/Users/Tsunami/Documents/hello.txt"
    content, err := ioutil.ReadFile(file)
    if err != nil {
        fmt.Println("read file err=%v", err)
    }
    //fmt.Printf("%v", content)         //[]byte
    fmt.Printf("%v", string(content)) //[]byte
    //因为没有显示的Open文件,因此也不需要显示的Close文件
    //因为,文件的Open和Close被封装到ReadFile函数内部
}
复制代码

2.写操作

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

name为打开的文件名,flag为打开模式,perm为文件权限,返回值file为文件句柄,err为错误返回

文件打开模式consts

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  // 如果可能,打开时清空文件
)
基本应用实例
使用os.OpenFile(),bufio.NewWriter(),*Writer的方法WriteString完成以下的任务

1)创建一个新文件,带缓存写入内容5句“hello,World”
复制代码
package main

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

func main() {
    filePath := "/Users/Tsunami/Documents/test1.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        fmt.Printf("open file err=&v\r\n", err)   //\r\n不同的编辑器换行符不一样

     return
  } 

//及时关闭file句柄

defer file.Close()
str :
= "hello,World\n" //\n表示换行

//写入时,使用带缓存的*Write
writer := bufio.NewWriter(file)

for i := 0; i < 5; i++ {
  writer.WriteString(str)
 }
//因为write是带缓存的,因此在调用WriteString时是先写入缓存的,因此需要调用Flush()将缓存中的数据写入到文件中,否则文件中没有数据。
writer.Flush()
}
复制代码

2)打开一个存在的文件,将原来的内容覆盖成新的内容10句“你好,世界”
复制代码
package main

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

func main() {
    //打开已经存在的文件
    filePath := "/Users/Tsunami/Documents/test1.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC, 0666) //os.O_TRUNC 表示清空,表示打开文件并清空
    if err != nil {
        fmt.Printf("open file err=&v\r\n", err) //\r\n不同的编辑器换行符不一样
        return
    }
    //及时关闭file句柄
    defer file.Close()
    str := "你好,世界\n" //\n表示换行
    //写入时,使用带缓存的*Write
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        writer.WriteString(str)
    }
    //因为write是带缓存的,因此在调用WriteString时是先写入缓存的,因此需要调用Flush()将缓存中的数据写入到文件中,否则文件中没有数据。
    writer.Flush()
}
复制代码

3)打开一个存在的文件,在原来的内容追加‘ABC!ENGILSH’
复制代码
package main

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

func main() {
    //打开已经存在的文件
    filePath := "/Users/Tsunami/Documents/test1.txt"
    file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0666) //os.O_APPEND 表示在原来的基础上追加
    if err != nil {
        fmt.Printf("open file err=&v\r\n", err) //\r\n不同的编辑器换行符不一样
        return
    }
    //及时关闭file句柄
    defer file.Close()
    str := "ABC,ENGLISH\n" //\n表示换行
    //写入时,使用带缓存的*Write
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        writer.WriteString(str)
    }
    //因为write是带缓存的,因此在调用WriteString时是先写入缓存的,因此需要调用Flush()将缓存中的数据写入到文件中,否则文件中没有数据。
    writer.Flush()
}
复制代码

4)打开一个存在的文件,将原来的内容读出显示在终端,并且追加5句“hello,北京”
复制代码
package main

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

func main() {
    //打开已经存在的文件
    filePath := "/Users/Tsunami/Documents/test1.txt"
    file, err := os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0666) //os.O_RDWR 表示读写,os.O_APPEND表示追加
    if err != nil {
        fmt.Printf("open file err=&v\r\n", err) //\r\n不同的编辑器换行符不一样
        return
    }
    //及时关闭file句柄
    defer file.Close()
    reader := bufio.NewReader(file)
    for {
        str, err := reader.ReadString('\n') //读取一行
        if err == io.EOF {                  //如果读取到文件末尾
            break
        }
        fmt.Println(str)
    }

    //先读取原来文件的内容,并显示在终端
    str := "你好,北京\n" //\n表示换行
    //写入时,使用带缓存的*Write
    writer := bufio.NewWriter(file)
    for i := 0; i < 3; i++ {
        writer.WriteString(str)
    }
    //因为write是带缓存的,因此在调用WriteString时是先写入缓存的,因此需要调用Flush()将缓存中的数据写入到文件中,否则文件中没有数据。
    writer.Flush()
}
复制代码

实例二

编写一个程序,将一个文件的内容,写入到另一个文件。注:这两个文件已经存在了。说明:使用ioutil.ReadFile/ioutil.WriteFile完成写文件的任务

复制代码
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    filePath := "/Users/Tsunami/Documents/test1.txt"
    filePath1 := "/Users/Tsunami/Documents/test2.txt"
    file, err := ioutil.ReadFile(filePath)
    if err != nil {
        fmt.Printf("open file err=&v\n", err)
        return
    }
    fmt.Println(string(file))
    err1 := ioutil.WriteFile(filePath1, file, 0666)
    if err1 != nil {
        fmt.Printf("write file err=&v\n", err)
    }
}
复制代码

实例三

拷贝文件

说明:将一张图片/电影/mp3拷贝到另外一个文件 使用io包的 io.Copy:func Copy(dst Writer, src Reader) (written int64, err error)函数进行拷贝。编写一个函数实现目标地址到目的地址的拷贝。io.Copy可以拷贝大文件

复制代码
package main

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

//自己编写一个函数,接收两个文件路径,srcFileName dstFileName
//func Copy(dst Writer, src Reader) (written int64, err error)
func CopyFile(srcFile string, dstFile string) (written int64, err error) {
    srcfile, err := os.Open(srcFile)
    if err != nil {
        fmt.Errorf("open file err=&v\n", err)
        return
    }
    defer srcfile.Close()
    reader := bufio.NewReader(srcfile)

    dstfile, err1 := os.OpenFile(dstFile, os.O_WRONLY|os.O_CREATE, 0666)
    if err1 != nil {
        fmt.Errorf("open file err=&v\n", err)
        return
    }
    defer dstfile.Close()
    writer := bufio.NewWriter(dstfile)

    return io.Copy(writer, reader)
}
func main() {
    srcFile := "/Users/Tsunami/Documents/miao.png"
    dstFile := "/Users/Tsunami/Documents/miaomiao.jpg"
    CopyFile(srcFile, dstFile)
}
复制代码

实例四

统计一个文件中含有英文、数字、空格及其他字符数量

复制代码
package main

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

//定义一个结构体,用于保存统计结果
type charCount struct {
    ChCount    int
    NumCount   int
    SpaceCount int
    OtherCount int
}

func main() {
    //思路:打开一个文档,创一个Reader
    //每读取一行,就去统计该行有多少个 英文、数字、空格和其他字符
    //然后将结果保存到一个结构体
    //如果case带有fallthrough,程序会继续执行下一条case,不会再判断下一条case的expr,如果之后的case都有fallthrough,default出会被执行。
    count := charCount{}
    filepath := "/Users/Tsunami/Documents/Hello.txt"
    file, err := os.Open(filepath)
    if err != nil {
        fmt.Printf("文件打开错误:%v", err)
        return
    }
    reader := bufio.NewReader(file)

    for {
        str, err := reader.ReadString('\n')
        if err == io.EOF {
            break
        }
        for _, v := range str {
            switch {
            case v >= 'a' && v <= 'z':
                fallthrough //穿透,如果这个case成功,下一个case不用判断就执行。
            case v >= 'A' && v <= 'Z':
                count.ChCount++
            case v >= '0' && v <= '9':
                count.NumCount++
            case v == ' ' || v == '\t':
                count.SpaceCount++
            default:
                count.OtherCount++

            }
        }
    }
    fmt.Println(count)
}
复制代码

 

 

 



posted @   潇潇暮鱼鱼  阅读(133)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2022-03-10 istio安装与升级
点击右上角即可分享
微信分享提示