开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 24天,点击查看活动详情
文件资源
os.Open()函数能够打开一个文件,返回一个*File和一个err。对得到的文件实例调用close()方法能够关闭文件
func main() {
file, err := os.Open("./07_package/07_file_test.txt") //路径以项目根目录为开始
//file, err := os.OpenFile("./07_package/07_file_test.txt", os.O_RDONLY, 0)
if err != nil {
fmt.Println("file open err:", err)
return
}
defer file.Close()
fmt.Println(file)
}
注意点:文件路径,是以项目根目录为开始
os.OpenFile()的使用:
func OpenFile(name string, flag int, perm FileMode) (*File, error) {}
其中:
-
name:要打开的文件名 -
flag:打开文件的模式。 模式有以下几种:- os.O_WRONLY 只写
- os.O_CREATE 创建文件
- os.O_RDONLY 只读
- os.O_RDWR 读写
- os.O_TRUNC 清空
- os.O_APPEND 追加
-
perm:文件权限,一个八进制数。r(读)04,w(写)02,x(执行)01
文件读写
方式1:os包读写
基本读取
func main() {
file, err := os.Open("./07_package/07_file_test.txt")
if err != nil {
fmt.Println("file open err:", err)
return
}
defer file.Close()
tmp := make([]byte, 128) //注意:这里只能读取到128个字节数据
n, err := file.Read(tmp)
if err != nil && err != io.EOF { //io.EOF代表读取到空文件或文件结尾,这个错误得排除掉
fmt.Println("file read err:", err)
return
}
fmt.Printf("读取的文件有%d字节数据\n", n)
fmt.Printf("读取的内容:%s\n", string(tmp[:n]))
}
上面的用法,有读取数据长度的局限性,所以得用下面的方法,循环去读取
循环读取
func main() {
file, err := os.Open("./07_package/07_file_test.txt")
if err != nil {
fmt.Println("file open err:", err)
return
}
defer file.Close()
//循环读取(要用io.EOF终止循环)
content := make([]byte, 0)
for {
tmp := make([]byte, 128)
n, err := file.Read(tmp)
if err == io.EOF {
fmt.Println("文件已读取完成")
break
}
if err != nil {
fmt.Println("file read err:", err)
return
}
content = append(content, tmp[:n]...)
}
fmt.Printf("读取的文件有%d字节数据\n", len(content))
fmt.Printf("读取的内容:%s\n", string(content))
}
写入数据:
func main() {
file, err := os.OpenFile("./07_package/07_file_test.txt", os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Println("file open err:", err)
return
}
defer file.Close()
str := "\nosWrite " + strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
file.Write([]byte(str))
n, _ := file.WriteString(str)
fmt.Printf("写入文件字节数:%d\n", n)
}
方式2:bufio包读写
读取
逐行读取文件数据,注意io.EOF读到尾部时,需要特殊处理下尾部的数据
func main() {
file, err := os.Open("./07_package/07_file_test.txt")
if err != nil {
fmt.Println("file open err:", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
//循环读取(指定按行定界符,使用io.EOF终止)
content := ""
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
if len(line) != 0 { //注意:这里是为了能读取到最后一行的数据
fmt.Printf(line)
content += line
}
fmt.Println("文件已读取完成")
break
}
if err != nil {
fmt.Println("reader.ReadString err:", err)
return
}
fmt.Printf(line)
content += line
}
fmt.Println("读取的内容:", content)
}
写入
func main() {
file, err := os.OpenFile("./07_package/07_file_test.txt", os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Println("file open err:", err)
return
}
defer file.Close()
writer := bufio.NewWriter(file)
str := "\nbufioWrite " + strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
n, _ := writer.WriteString(str) //将数据先写入缓存
writer.Flush() //将缓存中的内容写入文件
fmt.Printf("写入文件字节数:%d\n", n)
}
方式3:io/ioutil包读写
读取
能够读取完整的文件,只需要将文件名作为参数传入
func main() {
content, err := ioutil.ReadFile("./07_package/07_file_test.txt")
if err != nil {
fmt.Println("ioutil.ReadFile err:", err)
return
}
fmt.Println(string(content))
}
写入
会直接全量覆盖,不能指定按追加的方式写入。解决方法:写读取数据,拼接后再写入
func main() {
str := "\nioutilWrite " + strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
err := ioutil.WriteFile("./07_package/07_file_test.txt", []byte(str), 0666)
if err != nil {
fmt.Println("ioutil.WriteFile err:", err)
return
}
fmt.Println("ioutil.WriteFile success")
}
如果本文对你有帮助,欢迎点赞收藏加关注,如果本文有错误的地方,欢迎指出!