[go-每日一库] golang通过io/bufio库实现文件的读写及解封包操作
在日常操作中,对文件的操作比较多的是打开文件、关闭文件、读取内容、写入内容、打包、解包,今天分享个这些操作的基本case,用到的库也都是go自带的常用库,包括io、bufio、archive/zip等。
本文用到库的import:
import ( "archive/zip" "bufio" "fmt" "io" "io/ioutil" "log" "os" "strings" )
go官方提供的io,bufio库对文件进行相关操作
- 1.io库直接操作文件
- 2.bufio提供缓冲区操作文件
1.文件的基本操作-创建、打开、关闭、权限
直接上代码:
func main() { // 1.文件的基础操作,create/open/close/chmod -> go/io库 // 创建文件 create file f, err := os.Create("create.txt") if err != nil { log.Fatalf("get file info error: %s\n", err.Error()) } // 文件状态信息 file stats fileInfo, err := f.Stat() if err != nil { log.Fatalf("create file error: %s\n", err.Error()) } log.Printf("File Name is %s\n", fileInfo.Name()) log.Printf("File Permissions is %s\n", fileInfo.Mode()) log.Printf("File ModTime is %s\n", fileInfo.ModTime()) // 文件权限 chmod err = f.Chmod(0777) if err != nil { log.Fatalf("chmod file failed err=%s\n", err.Error()) } // 文件属者 chown, windows os 除外 err = f.Chown(os.Getuid(), os.Getgid()) if err != nil{ log.Fatalf("chown file failed err=%s\n", err) } // 确认文件属性修改成功 fileInfo, err = f.Stat() if err != nil{ log.Fatalf("get file info second failed err=%s\n", err) } log.Printf("File change Permissions is %s\n", fileInfo.Mode()) // 关闭文件 close err = f.Close() if err != nil{ log.Fatalf("close file failed err=%s\n", err) } // 删除文件 delete err = os.Remove("create.txt") if err != nil{ log.Fatalf("remove file failed err=%s\n", err) } }
2.文件的写入
直接上代码:
func main() { // 1.快写文件 fast write file -> os/ioutil, 封装openFile/write/close,一条龙服务 err := os.WriteFile("fastwrite.txt", []byte("Hi fast write\n"), 0666) if err != nil { log.Fatalf("fast write failed, err=%s\n", err.Error()) } // 2.按行写入文件, os、bufio没有直接提供按行写入,故调用os.WriteString、bufio.WriteString方法,再加入换行符 // 2.1 直接操作io data := []string{ "demo", "test", "123", } f, err := os.OpenFile("directIO.txt", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Fatalf("open file failed, err=%s\n", err.Error()) } // 写入数据 for _, line := range data { _, err = f.WriteString(line + "\n") if err != nil { log.Fatalf("write one line data failed, err=%s\n", err.Error()) } } _ = f.Close() // 2.2 缓冲区写入 buffer IO file, err := os.OpenFile("bufIO.txt", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Fatal(err.Error()) } // create file buf writer bufWriter := bufio.NewWriter(file) for i := 0; i < 3; i++ { // 写入string到buffer bytesWritten, err := bufWriter.WriteString("you are awesome\n") if err != nil { log.Fatal(err.Error()) } log.Printf("Bytes written: %d\n", bytesWritten) } // write memory to disk err = bufWriter.Flush() if err != nil { log.Fatal(err.Error()) } _ = file.Close() // 3.偏移量offset写入 data1 := []byte{ 0x41, // A 0x73, // s 0x20, // space 0x20, // space 0x67, // g } f, err = os.OpenFile("offset.txt", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Println(err.Error()) } // 先写入数据 _, err = f.Write(data1) replace := []byte{ 0x6F, // o 0x6E, // n } _, err = f.WriteAt(replace, 2) if err != nil { log.Println(err.Error()) } _ = f.Close() // 4.write with buffer // io直写是方便,同样如果频繁操作的话,会增加CPU的中断频率,可以通过内存缓冲区减少IO操作,即buffer io 写入 // user program -> memory(buffer) -> disk f, err = os.OpenFile("bufferWrite.txt", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Println(err.Error()) } // create buf writer buf := bufio.NewWriter(f) // size=4096 0r 4k // write string to buffer bytesWritten, err := buf.WriteString("bufferio write\n") if err != nil { log.Println(err) } log.Printf("bytes written: %d\n", bytesWritten) // check buffer bytes count unflushedBufSize := buf.Buffered() log.Printf("bytes buffered: %d\n", unflushedBufSize) // 未使用的缓存的大小,check remain bytes which can use bytesAvailable := buf.Available() log.Printf("Available buffer: %d\n", bytesAvailable) // 刷盘 _ = buf.Flush() // close file _ = f.Close() }
3.读取文件
func main() { // 3.1 读取全文 // os.readFile data, err := os.ReadFile("bufIO.txt") if err != nil { log.Println(err.Error()) } log.Println("read %s content is %s\n", "bufIO.txt", string(data)) // ioutil.readall file, err := os.Open("bufIO.txt") if err != nil { log.Println(err) } content, err := ioutil.ReadAll(file) log.Printf("read %s content is %s\n", "bufIO.txt", content) file.Close() // 3.2 read by line // os.read -> read by bytes length // bufio.readLine/readBytes/readString -> read by line file, err = os.OpenFile("bufIO.txt", os.O_RDONLY, 0666) if err != nil { log.Println(err.Error()) } bufReader := bufio.NewReader(file) // read by line, use for-loop for { linBytes, err := bufReader.ReadBytes('\n') //bufReader.ReadLine() // low level use line := strings.TrimSpace(string(linBytes)) if err != nil && err != io.EOF { log.Println(err.Error()) } if err == io.EOF { break } log.Printf("readline %s every line data is %s\n", "bufIO.txt", line) } _ = file.Close() // 3.3 read file by block // os库的Read方法 // os库配合bufio.NewReader调用Read方法 // os库配合io库的ReadFull、ReadAtLeast方法 // bufio.NewReader file, err = os.OpenFile("bufIO.txt", os.O_RDONLY, 0666) if err != nil { log.Println(err) } // create reader r := bufio.NewReader(file) // read 2 bytes every time buf := make([]byte, 2) for { n, err := r.Read(buf) if err != nil && err != io.EOF { log.Println(err.Error()) } if n == 0 { break } log.Printf("readByte %s every read 2 byte is %s\n", "bufIO.txt", string(buf[:n])) } _ = file.Close() // os.read file, err = os.OpenFile("bufIO.txt", os.O_RDONLY, 0666) if err != nil { log.Println(err.Error()) } buf = make([]byte, 2) for { n, err := file.Read(buf) if err != nil && err != io.EOF { log.Println(err.Error()) } if n == 0 { break } log.Printf("readByte %s every read 2 byte is %s\n", "bufIO.txt", string(buf[:n])) } _ = file.Close() // io.ReadAtLeast() file, err = os.OpenFile("bufIO.txt", os.O_RDONLY, 0666) if err != nil { log.Println(err.Error()) } buf = make([]byte, 2) for { n, err := io.ReadAtLeast(file, buf, 1) if err != nil && err != io.EOF { log.Println(err.Error()) } if n == 0 { break } log.Printf("readByte %s every read 2 byte is %s\n", "bufIO.txt", string(buf[:n])) } _ = file.Close() }
4.打包、解包
func main() { // zip 解包 // open a zip archive for reading r, err := zip.OpenReader("txt.zip") if err != nil { log.Println(err) } defer r.Close() // iterate through files in the archive && print their contents for _, f := range r.File { fmt.Printf("content of %s:\n", f.Name) rc, err := f.Open() if err != nil { log.Println(err.Error()) } _, err = io.CopyN(os.Stdout, rc, 68) if err != nil { log.Println(err.Error()) } rc.Close() } // zip 打包 // create a archive zipFile, err := os.Create("out.zip") if err != nil { log.Println(err.Error()) } // create new zip archive w := zip.NewWriter(zipFile) // add some file to the archive var files = []struct{ Name, Body string }{ {"asong.txt", "This archive contains some text files."}, {"todo.txt", "Get animal handling licence.\nWrite more examples."}, } for _, file := range files { // create file f, err := w.Create(file.Name) if err != nil { log.Println(err.Error()) } // write content _, err = f.Write([]byte(file.Body)) if err != nil { log.Println(err.Error()) } } // check error on close err = w.Close() if err != nil { log.Println(err.Error()) } }
参考文档:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性