在 Go 语言中,有多种方式可以读取文件,其中包括 os、bufio 和 ioutil 等包。它们之间的主要区别在于操作的文件对象以及读取方式的不同。
首先,os 包提供了基本的文件读取和写入功能,可以使用 os.Open() 函数打开文件,并使用 os.File 对象进行读取和写入。os.File 对象支持直接读取文件的内容、按行读取和缓冲读取等方式。
其次,bufio 包提供了带有缓冲区的读写操作,使用 bufio 包可以轻松地实现按行读取文件等操作。bufio 包还支持将文件读取到内存中的缓冲区中,以便进行更高效的读取和处理。
最后,ioutil 包提供了更加简单的文件读取方式,通过一行代码就可以将文件内容读取到内存中。ioutil 包的 ReadFile() 函数可以读取整个文件的内容,并将其作为字节切片返回。
需要注意的是,使用 ioutil 包读取文件时,文件的大小不能超过内存的大小,否则将导致程序崩溃。而 os 和 bufio 包则没有这个限制,可以处理非常大的文件。因此,在实际开发中需要根据文件大小和读取方式的需求选择合适的包进行文件操作
os.File
创建、读取、写入
file, _ := os.Create(wd + "/1.txt")
fmt.Println(file.Name())
//写入文件,可以制定打开文件的目的,是只读花式只写等,还要传入文件的权限
f, err := os.OpenFile(wd+"/1.txt", os.O_WRONLY, 777)
if err != nil {
fmt.Println(err)
}
//以只读的方式写入,是写不成功的,实际就是调用了OpenFile文件
f, err = os.Open(wd + "/1.txt")
defer f.Close()
//read读取
buf := make([]byte, 3)
var str string
//从文件中读取
for {
n, err := f.Read(buf)
if err != nil {
if err == io.EOF {
break
}
}
str += string(buf[:n])
}
n, err := f.WriteString("111,2222,3334,5,,4,655,655")
if err != nil {
fmt.Println("::", n, err)
}
f.Close()
其他操作
// 创建文件
file, err := os.Create("filename.txt")
if err != nil {
fmt.Println("Create file error:", err)
return
}
defer file.Close()
// 重命名文件
err := os.Rename("filename.txt", "newname.txt")
if err != nil {
fmt.Println("Rename file error:", err)
return
}
// 删除文件
err := os.Remove("filename.txt")
if err != nil {
fmt.Println("Remove file error:", err)
return
}
获取文件状态
//获取文件状态
finfo, err := f.Stat()
fmt.Println("是否是目录:", finfo.IsDir())
fmt.Println("修改时间:", finfo.ModTime().String())
fmt.Println("文件的名字:", finfo.Name())
fmt.Println("文件的size:", finfo.Size())
fmt.Println("文件的权限:", finfo.Mode().String())
fmt.Println("传的参数:", os.Args[0])
//环境变量
name, _ := os.Hostname()
fmt.Println("获取主机名:", name)
enarg := os.Getenv("ZSH")
fmt.Println("获取环境变量:", enarg)
fmt.Println("获取环境变量:", enarg)
//func Exit(code int) // 让当前程序以给出的状态码(code)退出。一般来说,状态码0表示成功,非0表示出错。程序会立刻终止,defer的函数不会被执行。
//func Setenv(key, value string) error // 设置一个环境变量,失败返回错误,经测试当前设置的环境变量只在 当前进程有效(当前进程衍生的所以的go程都可以拿到,子go程与父go程的环境变量可以互相获取);进程退出消失
/*
func Clearenv() // 删除当前程序已有的所有环境变量。不会影响当前电脑系统的环境变量,这些环境变量都是对当前go程序而言的
func Exit(code int) // 让当前程序以给出的状态码(code)退出。一般来说,状态码0表示成功,非0表示出错。程序会立刻终止,defer的函数不会被执行。
func Getuid() int // 获取调用者的用户id
func Geteuid() int // 获取调用者的有效用户id
func Getgid() int // 获取调用者的组id
func Getegid() int // 获取调用者的有效组id
func Getgroups() ([]int, error) // 获取调用者所在的所有组的组id
func Getpid() int // 获取调用者所在进程的进程id
func Getppid() int // 获取调用者所在进程的父进程的进程id
*/
// 判断字c是否是一个路径分隔符
fmt.Println(os.IsPathSeparator('/'), os.IsPathSeparator(':'))
//判断一个错误是否表示一个文件或文件夹是否已存在,ErrExist和一些系统调用错误会使它返回真。
fmt.Println(os.IsExist(os.ErrExist), os.IsExist(errors.New("file already exists")))
finfo, err = f.Stat()
finfo2, err := f.Stat()
//是否指向同一文件
fmt.Println(os.SameFile(finfo, finfo2))
ioutil
一次读取整个文件
// 通过ioutil包中的ReadFile函数读取文件内容
content, err := ioutil.ReadFile("filename.txt")
if err != nil {
fmt.Println("Read file error:", err)
return
}
一次写入整个内容
data := []byte("Hello, world!")
err := ioutil.WriteFile("test.txt", data, 0644)
if err != nil {
fmt.Println("Write file error:", err)
return
}
读取目录
ioutil 包提供了 ioutil.ReadDir() 方法用于读取目录,其函数原型如下:
func ReadDir(dirname string) ([]os.FileInfo, error)
该方法接收一个目录名作为参数,返回一个文件信息数组和一个错误值。如果读取目录成功,将返回文件信息数组和 nil,否则返回 nil 和一个错误对象。
下面是一个使用 ioutil.ReadDir() 方法读取目录的例子:
package main
import (
"fmt""io/ioutil"
)
func main() {
files, err := ioutil.ReadDir(".")
if err != nil {
fmt.Println("Read dir error:", err)
return
}
for _, file := range files {
fmt.Println(file.Name())
}
}
bufio
读取
// 打开文件
file, err := os.Open("test.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 创建 bufio.Reader 对象
reader := bufio.NewReader(file)
// 读取文件内容
for {
line, err := reader.ReadString('\n')
if err != nil && err != io.EOF {
log.Fatal(err)
}
if err == io.EOF {
break
}
fmt.Print(line)
}
写入
bufio 包也提供了带缓冲的写入操作,使用 bufio 写入文件的步骤如下:
创建 bufio.Writer 对象
写入文件内容
刷新缓冲区
关闭文件
// 创建 bufio.Writer 对象
file, err := os.Create("test.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
writer := bufio.NewWriter(file)
// 写入文件内容
text := "Hello, World!\n"
for i := 0; i < 10; i++ {
_, err := writer.WriteString(text)
if err != nil {
log.Fatal(err)
}
}
// 刷新缓冲区
err = writer.Flush()
if err != nil {
log.Fatal(err)
}