file 是一个地址,指向文件的句柄
file 是一个地址,指向文件的句柄
err 等于 nil 表示打开文件成功
package main
import (
"fmt"
"os"
)
func main() {
// 只读的方式打开文件
// file 是一个地址,指向文件的句柄
// err 等于 nil 表示打开文件成功
// err 不等于 nil 表示打开文件失败
file, err := os.Open("./45.md")
if err != nil {
fmt.Println(err)
return
}
// 打开文件之后,你一定要记得关闭文件哈;否则会造成内存泄漏
defer file.Close()
fmt.Println(file)
}
输出:&{0xfa0de47c240}
读取某个文件
package main
import (
"fmt"
"os"
)
func main() {
// 只读的方式打开文件
// file 是一个地址,指向文件的句柄
file, err := os.Open("./45.md")
if err != nil {
fmt.Println(err)
return
}
// 打开文件之后,你一定要记得关闭文件哈;否则会造成内存泄漏
defer file.Close()
fmt.Println(file)
// 创建一个byte类型的切片
var tempSlice = make([]byte, 128)
// 从文件中读取数据;每次只能读取128字节;因为tempSlice是一个字节数组,大小为128,所以只能读取128字节
// file.read(tempSlice) 的参数是一个byte类型的切片,返回值是一个读取到字节数的整数,以及一个错误值
n, err := file.Read(tempSlice)
if err != nil {
fmt.Println("读取文件失败")
fmt.Println(err)
return
}
fmt.Printf("%d 字节", n)
fmt.Printf("读取到的内容", string(tempSlice))
}
读取文件的全部内容,出现问题
我们发现读取到的内容是不全的哈;
这是因为我们每次只能读取128字节,而文件的大小可能大于128字节。
所以,我们需要使用一个循环,每次读取128字节,直到读取到文件的末尾。
读取文件的全部内容
package main
import (
"fmt"
"io"
"os"
)
func main() {
// 只读的方式打开文件
// file 是一个地址,指向文件的句柄
file, err := os.Open("./45.md")
if err != nil {
fmt.Println(err)
return
}
// 打开文件之后,你一定要记得关闭文件哈;否则会造成内存泄漏
defer file.Close()
fmt.Println(file)
var strSlice []byte
// 创建一个byte类型的切片;每次都会读取128字节。如果不足128字节,那么就会出现问题
var tempSlice = make([]byte, 128)
for {
n, err := file.Read(tempSlice)
// 读取到文件末尾,err返回io.EOF
if err == io.EOF {
fmt.Println("读取完成")
break
}
if err != nil {
fmt.Println("读取文件失败")
return
}
// 把每次读取到的内容,追加到strSlice中(只取实际读到的n个字节)
strSlice = append(strSlice, tempSlice[:n]...)
}
fmt.Println("读取到的内容:", string(strSlice))
}
现在我们就可以把文件的全部内容给读取出来。
容易出现的其他问题:
最后一次读取通常不足 128 字节,tempSlice里会残留上一轮的数据。
所以必须用[:n] 截取有效部分,不能用整个tempSlice
n, err := file.Read(tempSlice)
// ...
strSlice = append(strSlice, tempSlice[:n]...)
一次读取一行文件的内容
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// file 是一个地址,指向文件的句柄
file, err := os.Open("./45.md")
if err != nil {
fmt.Println(err)
return
}
// 打开文件之后,你一定要记得关闭文件哈;否则会造成内存泄漏
defer file.Close()
// 创建一个bufio.Reader类型的变量,指向读取文件的内容
reader := bufio.NewReader(file)
// 每次读取一行内容
str, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
return
}
fmt.Println(str)
}
for循环读取文件的全部内容:一次读取一行文件的内容
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
// file 是一个地址,指向文件的句柄
file, err := os.Open("./45.md")
if err != nil {
fmt.Println(err)
return
}
// 打开文件之后,你一定要记得关闭文件哈;否则会造成内存泄漏
defer file.Close()
// 定义一个字符串,用来存储文件的内容
var fileStr string
// 创建一个bufio.Reader类型的变量,指向读取文件的内容
reader := bufio.NewReader(file)
for {
// 每次读取一行内容
str, err := reader.ReadString('\n')
// 如果读取到文件的末尾,就跳出循环
if err == io.EOF {
// 否则会出现文件文件读取不完的情况(文件中间出现空白行)
fileStr += str
break
}
if err != nil {
fmt.Println(err)
return
}
fileStr += str
}
fmt.Println(fileStr)
}
文件较小的话,可以通过这样的方式一次性全部读取出来
package main
import (
"fmt"
"io/ioutil"
)
func main() {
byteStr, err := ioutil.ReadFile("./45.md")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(byteStr))
}
name 表示你要打开的文件名
flag 表示你要打开的文件模式,有下面这几种模式
OS.O_WRONLY:只写
Os.O_CREATE:创建文件
Os.O_RDONLY:只读
OS.O_RDWR:读写
Os.O_TRUNC:清空
OS.O_APPEND:追加
perm 表示文件权限
perm:文件权限,一个八进制数。r(读)04,w(写)02,×(执行)01。
给文件写入数据
package main
import (
"fmt"
"os"
)
func main() {
// 打开文件
// name 表示你要打开的文件名
// flag 表示你要打开的文件模式
// - `os.O_CREATE` :文件不存在就创建
// - `os.O_WRONLY` :只写模式
// - `os.O_TRUNC` :打开时清空原有内容
// 权限`0666` 是八进制读写权限(在 Windows 下基本不起作用,主要对 Linux 有效)
file, err := os.OpenFile("test.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
file.WriteString("hello world")
}
现在这样,就可以给文件中写入数据了。
通过循环给文件写入数据
package main
import (
"fmt"
"os"
"strconv"
)
func main() {
// 打开文件
// name 表示你要打开的文件名
// flag 表示你要打开的文件模式
// - `os.O_CREATE` :文件不存在就创建
// - `os.O_WRONLY` :只写模式
// - `os.O_TRUNC` :打开时清空原有内容
// 权限`0666` 是八进制读写权限(在 Windows 下基本不起作用,主要对 Linux 有效)
file, err := os.OpenFile("test.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
for i := 0; i < 10; i++ {
// strconv.Itoa(i) 将整数转换为字符串
// "\n" 表示换行
file.WriteString("hello world " + strconv.Itoa(i) + "\n")
}
}
通过file.Write(\[\]byte(str))来写入文件
package main
import (
"fmt"
"os"
)
func main() {
// 打开文件
// name 表示你要打开的文件名
// flag 表示你要打开的文件模式
// - `os.O_CREATE` :文件不存在就创建
// - `os.O_WRONLY` :只写模式
// - `os.O_TRUNC` :打开时清空原有内容
// 权限`0666` 是八进制读写权限(在 Windows 下基本不起作用,主要对 Linux 有效)
file, err := os.OpenFile("testFile.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
var str = "直接写入数据"
// 写入数据
// []byte(str) 将字符串转换为字节数组
file.Write([]byte(str))
}
bufio.NewWriter(file)来写入文件
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 打开文件
// name 表示你要打开的文件名
// flag 表示你要打开的文件模式
// - `os.O_CREATE` :文件不存在就创建
// - `os.O_WRONLY` :只写模式
// - `os.O_TRUNC` :打开时清空原有内容
// - `os.O_APPEND` :追加模式
// 权限`0666` 是八进制读写权限(在 Windows 下基本不起作用,主要对 Linux 有效)
file, err := os.OpenFile("testFile.txt", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
writer := bufio.NewWriter(file)
// 表示写入到缓存中去
writer.WriteString("hello golang")
// 表示将缓存中的数据写入到文件中
writer.Flush()
}
ioutil.WriteFile 来写入文件
package main
import (
"fmt"
"io/ioutil"
)
func main() {
str := "hello golang"
// 写入文件,会覆盖原有内容
// []byte(str) 将字符串转换为字节数组
err := ioutil.WriteFile("testFile.txt", []byte(str), 0666)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("写入成功")
}