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) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2022-03-10 istio安装与升级