Golang: 常用的文件读写操作

您所在的位置:网站首页 c语言按字节读取文件 Golang: 常用的文件读写操作

Golang: 常用的文件读写操作

2023-09-18 23:46| 来源: 网络整理| 查看: 265

Go 语言提供了很多文件操作的支持,在不同场景下,有对应的处理方式,今天就来系统地梳理一下,几种常用的文件读写的形式。

一、读取文件内容 1、按字节读取文件

这种方式是以字节为单位来读取,相对底层一些,代码量也较大,我们看下面代码:

// read-bytes.go package main import ( "fmt" "io" "os" ) func main() { file, _ := os.Open("test.txt") defer file.Close() // 字节切片缓存 存放每次读取的字节 buf := make([]byte, 1024) // 该字节切片用于存放文件所有字节 var bytes []byte for { // 返回本次读取的字节数 count, err := file.Read(buf) // 检测是否到了文件末尾 if err == io.EOF { break; } // 取出本次读取的数据 currBytes := buf[:count] // 将读取到的数据 追加到字节切片中 bytes = append(bytes, currBytes...) } // 将字节切片转为字符串 最后打印出来文件内容 fmt.Println(string(bytes)) } 2、结合 ioutil 来读取

如果我们不想那么麻烦,可以结合 ioutil 来精简上面的代码:

// read-with-util.go package main import ( "fmt" "io/ioutil" "os" ) func main() { file, _ := os.Open("test.txt") defer file.Close() // ReadAll接收一个io.Reader的参数 返回字节切片 bytes, _ := ioutil.ReadAll(file) fmt.Println(string(bytes)) }

由于 os.File 也是 io.Reader 的实现,我们可以调用 ioutil.ReadAll(io.Reader) 方法,将文件所有字节读取出来,省去了使用字节缓存循环读取的过程。

3、仅使用 ioutil 包来完成读取操作:

为了进一步简化文件读取操作,ioutil 还提供了 ioutil.ReadFile(filename string) 方法,一行代码搞定读取任务:

// read-by-util.go package main import ( "fmt" "io/ioutil" ) func main() { bytes, _ := ioutil.ReadFile("test.txt") fmt.Println(string(bytes)) } 4、逐行读取:

有时候为了便于分析处理,我们希望能够逐行读取文件内容,这个时候可以 Scanner 来完成:

// read-line-by-line.go package main import ( "bufio" "fmt" "os" ) func main() { file, _ := os.Open("test.txt") defer file.Close() // 接受io.Reader类型参数 返回一个bufio.Scanner实例 scanner := bufio.NewScanner(file) var count int for scanner.Scan() { count++ // 读取当前行内容 line := scanner.Text() fmt.Printf("%d %s\n", count, line) } }

这简直就是 java.util.Scanner 翻版嘛,并且 Go 语言中的 Scanner 也可以接收不同的输入源,比如 os.Stdin 等。

上面代码直接打印出了每一行的数据,如果大家想得到最终文件的内容,可以创建一个字符串切片,每次逐行扫描时,将当前行内容追加到切片中即可。

以上就是几种常用的文件读取方式,当然还有其他更高级的方式,有机会再做总结。

二、写入文件操作 1、使用 ioutil 完成写入操作

上面我们介绍了 ioutil.ReadFile(filename string),与之对应地有 ioutil.WriteFile(filename string, ...) 方法,可以轻松完成写入操作:

// write-by-util.go package main import ( "io/ioutil" ) func main() { data := []byte("hello goo\n") // 覆盖式写入 ioutil.WriteFile("test.txt", data, 0664) }

我们看到,WriteFile() 方法需要传入三个参数,它的完整签名是:ioutil.WriteFile(filename string, data []byte, perm os.FileMode)。如果文件不存在,则会根据指定的权限创建文件,如果存在,则会先清空文件原有内容,然后再写入新数据。

需要注意最后一个参数,它是一个无符号 32 位整数,表示当前文件的权限,也是标准的 Unix 文件权限格式。

Unix 使用 -rwxrwxrwx 这样的形式来表示文件权限,其中:

第1位:文件属性,- 表示是普通文件,d 表示是一个目录 第2-4位:文件所有者的权限 第5-7位:文件所属用户组的权限 第8-10位:其他人的权限

在权限设置中:

r 表示 read,值为 4 w 表示 write,值为 2 x 表示 exec,值为 1

下面我们通过 os.FileMode 测试一下:

package main import ( "fmt" "os" ) func showMode(code int) { fmt.Println(os.FileMode(code).String()) } func main() { showMode(0777) showMode(0766) showMode(0764) }

运行程序,控制台打印如下:

-rwxrwxrwx -rwxrw-rw- -rwxrw-r-- 2、通过File句柄完成写入操作

上面我们曾使用过 os.Open(name string) 方法,这个方法是以只读方式打开文件的,os 包还提供了 os.OpenFile(name string, flag int, perm FileMode) 方法,通过指定额外的 读写方式 和 文件权限 参数,使文件操作变得更为灵活。

其中,flag 有以下几种常用的值:

os.O_CREATE: create if none exists 不存在则创建 os.O_RDONLY: read-only 只读 os.O_WRONLY: write-only 只写 os.O_RDWR: read-write 可读可写 os.O_TRUNC: truncate when opened 文件长度截为0:即清空文件 os.O_APPEND: append 追加新数据到文件

在打开文件之后,我们可以通过 Write() 和 WriteString() 方法写入数据,最后通过 Sync() 方法将数据持久化到磁盘:

// write-by-file-descriptor.go package main import ( "fmt" "os" ) // 打印写入的字节数 func printWroteBytes(count int) { fmt.Printf("wrote %d bytes\n", count) } func main() { // 以指定的权限打开文件 file, _ := os.OpenFile("test2.txt", os.O_RDWR | os.O_APPEND | os.O_CREATE, 0664) defer file.Close() data := []byte("hello go\n") // 写入字节 count, _ := file.Write(data) printWroteBytes(count) // 写入字符串 count, _ = file.WriteString("hello world\n") printWroteBytes(count) // 确保写入到磁盘 file.Sync() } 3、通过bufio包完成写入操作

这种方式其实是在 File 句柄上做了一层封装,调用方式和上面直接写入非常相似,大家仅做个参考:

// write-with-bufio.go package main import ( "bufio" "fmt" "os" ) func printWroteBytes(count int) { fmt.Printf("wrote %d bytes\n", count) } func main() { file, _ := os.OpenFile("test.txt", os.O_RDWR | os.O_APPEND | os.O_CREATE, 0664) defer file.Close() // 获取bufio.Writer实例 writer := bufio.NewWriter(file) // 写入字符串 count, _ := writer.Write([]byte("hello go\n")) fmt.Printf("wrote %d bytes\n", count) // 写入字符串 count, _ = writer.WriteString("hello world\n") fmt.Printf("wrote %d bytes\n", count) // 清空缓存 确保写入磁盘 writer.Flush() }

以上就是常用的文件读写方式,今天就总结到这里吧,后续有机会再探讨更多内容。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3