go 之文件操作
Posted flash55
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go 之文件操作相关的知识,希望对你有一定的参考价值。
文件操作要理解一切皆文件。
Go 在 os 中提供了文件的基本操作,包括通常意义的打开、创建、读写等操作,除此以外为了追求便捷以及性能上,Go 还在 io/ioutil 以及 bufio 提供一些其他函数供开发者使用
操作File文件类型
go中打开文件常用os.open,需要注意的是os.open只接收一个文件名参数,默认只有只读权限,文件的读写 flag
是以常量的形式定义如下
const ( // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified. O_RDONLY int = syscall.O_RDONLY // open the file read-only. O_WRONLY int = syscall.O_WRONLY // open the file write-only. O_RDWR int = syscall.O_RDWR // open the file read-write. // The remaining values may be or‘ed in to control behavior. O_APPEND int = syscall.O_APPEND // append data to the file when writing. O_CREATE int = syscall.O_CREAT // create a new file if none exists. O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist. O_SYNC int = syscall.O_SYNC // open for synchronous I/O. O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened. )
文件打开格式如
file, err := os.Open("text.txt")
文件读取
os.open打开文件后付给file然后通过read的方法读取并接收一个buf []byte 的参数类型,读取到文件末尾会返回0以及 io.EOF,可以通过0或者io.EOF进行判断文件是否读取完毕。
package main import ( "os" "fmt" ) func main() file, err := os.Open("text.txt") if err != nil fmt.Println(err) buf := make([]byte, 126) n, err := file.Read(buf) if err != nil fmt.Println(err) fmt.Printf("%d = %q", n, buf)
如果想在读取文件的时候加上权限可以使用os.openFile
package main import ( "log" "os" ) func main() file, err := os.OpenFile("test.txt", os.O_WRONLY, 0666) if err != nil if os.IsPermission(err) log.Println("Error: Write permission denied.") file.Close() // Test read permissions file, err = os.OpenFile("test.txt", os.O_RDONLY, 0666) if err != nil if os.IsPermission(err) log.Println("Error: Read permission denied.") file.Close()
注意的是在os.openFile后可根权限设置
os.O_WRONLY 只写 os.O_CREATE 创建文件 os.O_RDONLY 只读 os.O_RDWR 读写 os.O_TRUNC 清空 os.O_APPEND 追加
os.open循环读取
package main import ( "os" "fmt" ) func main() userFile := "test.txt" fin,err := os.Open(userFile) defer fin.Close() if err != nil fmt.Println(userFile,err) return buf := make([]byte, 1024) for n, _ := fin.Read(buf) if0 == n break os.Stdout.Write(buf[:n])
这里os.open只是提供了简单的read读取文件方法,写文件时还需要调用上面的提到的os.oenFile方法。
当然在go中还提供了bufil包进行文件的一次列操作。
bufio
bufio 顾名思义就是带 buffer 的 IO,由于频繁读写磁盘会有相当的性能开销,因为一次磁盘的读写就是一次系统的调用,所以 Go 提供了一个 buffer 来缓冲读写的数据,比如多次写磁盘 bufio 就会把数据先缓冲起来,待 buffer 装满之后一次性写入,又比如多次读数据,bufio 会预先按照 buffer 的大小(一般是磁盘 block size 的整数倍)尽量多的读取数据,也就是采用预读的技术以提高读的性能。bufio 提供了 Reader 、 Writer、 Scanner 来进行文件的读写,其中 Reader 和 Scanner 都支持按行读取文件。
Reader
package main import ( "bufio" "fmt" "io" "os" ) // bufio按行读取示例 func main() file, err := os.Open("text.txt") if err != nil fmt.Println("open file failed, err:", err) return defer file.Close() reader := bufio.NewReader(file) for line, err := reader.ReadString(‘\n‘) //注意是字符 if err == io.EOF fmt.Println("文件读完") break if err != nil fmt.Println("read file failed, err:", err) return fmt.Print(line)
在上面的栗子中,只是简单减少reader 中的一个ReadString方法,而Scanner中的内置方法基本与其类似,只是方法名不同而已。
文件的写入
os.openFile提供了WriteString和Write两种方法,具体使用哪种根据个人需求。如下
package main import ( "os" "fmt" ) func main() file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) if err != nil fmt.Println("open file failed, err:", err) return defer file.Close() str := "你好" file.Write([]byte(str)) //写入字节切片数据 file.WriteString(str) //直接写入字符串数据
bufio.Writer 进行文件输出
bufio 提供了 Writer 来进行高效的输出。实际上是一个内部包含 buffer 的特殊 struct。
type Writer struct err error buf []byte n int wr io.Writer
buf 这个 field 就是缓冲输出内容的,当满足指定 size 之后,Writer 才会把 buf 中的内容通过 wr 写到输出对象。
package main import ( "os" "fmt" "bufio" ) func main() file, err := os.OpenFile("text.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) if err != nil fmt.Println("open file failed, err:", err) return defer file.Close() writer := bufio.NewWriter(file) for i := 0; i < 10; i++ writer.WriteString("hello\n") //将数据先写入缓存 writer.Flush() //将缓存中的内容写入文件
ioutil 包的文件读写
最后要提到的文件读写操作的ioutil,不同于上面介绍的方法,ioutil提供的WriteFile, ReadFile 可以直接对文件进行写入和读取,省去了一个打开的过程。
package main import ( "io/ioutil" "fmt" ) func main() str := "hello" err := ioutil.WriteFile("text.txt", []byte(str), 0666) if err != nil fmt.Println("write file failed, err:", err) return
文件拷贝
package main import ( "os" "log" "io" ) func main() originalFile, err := os.Open("text.txt") if err != nil log.Fatal(err) defer originalFile.Close() newFile, err := os.Create("test_copy.txt") if err != nil log.Fatal(err) defer newFile.Close() bytesWritten, err := io.Copy(newFile, originalFile) if err != nil log.Fatal(err) log.Printf("Copied %d bytes.", bytesWritten) err = newFile.Sync() if err != nil log.Fatal(err)
以上是关于go 之文件操作的主要内容,如果未能解决你的问题,请参考以下文章