1 打开文件
1.1 os.OpenFile()
函数定义:
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
flag:
- os.O_CREATE : 不存在就创建文件
- os.O_RDWR : 赋予读写权限
- os.O_APPEND : 新数据以追加的方式写入文件(即写入到最后一行)
perm:
- 0777:创建了一个普通文件,所有人拥有所有的读、写、执行权限
- 0666:创建了一个普通文件,所有人拥有对该文件的读、写权限,但是都不可执行
- 0644:创建了一个普通文件,文件所有者对该文件有读写权限,用户组和其他人只有读权限,没有执行权限
1.2 os.Open()
函数定义:func Open(name string) (*File, error)
注意:os.Open其实是os.OpenFile()的只读模式,自然就没有flag和perm参数
2 关闭文件
2.1 file.Close()
函数定义:func (f *File) Close() error
3 创建文件
3.1 os.Create()
函数定义:
func Create(name string) (file *File, err Error)
4 读文件
4.1 os.ReadFile()
函数定义:func ReadFile(name string) ([]byte, error)
使用注意:os.ReadFile()是读取整个文件,一般用于小文件
代码示例:
package main
import(
"fmt"
"os"
"strings"
)
func check(err error){
if err!=nil{
panic(err)
}
}
func main(){
content,err:=os.ReadFile("tmp/dat.txt")
//"tmp/dat.txt"是我在project文件夹下创建的文件
check(err)
fmt.Println(string(content))
//将[]type类型的content强转为string类型
}
4.2 ioutil.ReadFile()
注意:从 Go 1.16 开始,ioutil.ReadFile 就等价于 os.ReadFile,二者是完全一致的
4.3 ioutil.ReadAll()
函数定义:func ReadAll(r io.Reader) ([]byte, error)
其实io.Reader还是file*类型
4.4 读取文件综合代码示例
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
//1读取整个文件
//1.1直接指定文件名读取
//os.ReadFile//返回的是字节数组
content, err := os.ReadFile("tmp/dat.txt")
check(err)
fmt.Println(string(content))
//ioutil.ReadFile
content, err = ioutil.ReadFile("tmp/dat.txt")
check(err)
fmt.Println(string(content))
//在 Go 1.16 开始,ioutil.ReadFile 就等价于 os.ReadFile,二者是完全一致的
//1.2先创建 句柄(文件指针/流) 在读取
//仅是读取的话,可以使用高级函数os.Open()*file{}
file, err := os.Open("./tmp/dat.txt") //返回了一个文件指针(流)
check(err)
defer file.Close()
content, err = ioutil.ReadAll(file) //ioutil.ReadFile()里形参为文件指针
fmt.Println(string(content)) //强转
//ioutil.ReadFile(*file)
//os.Open()是只读模式的os.OpenFile()
//所以可以直接使用os.OpenFile()
file, err = os.OpenFile("./tmp/dat.txt", os.O_RDONLY, 0)
check(err)
//我只能说尽量用os.OpenFile(name,)
//2每次只读取一行,解决内存占用过大的问题
//bufio.ReadBytes("\n")和bufio.ReadString("\n")
//2.1bufio.ReadBytes("\n")
file, err = os.Open("tmp/dat.txt") //先打开文件并创建句柄
check(err)
r := bufio.NewReader(file) //利用句柄和bufio.NewReader创建reader
for {
lineBytes, err := r.ReadBytes('\n') //读取一行
////读取错误返回nil,读取delim之前遇到错误返回io.EOF
// If ReadBytes encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF).
//[]byte,err:=reader.ReadBytes(delim byte)
line := strings.TrimSpace(string(lineBytes)) //需要强转在剪切
//str1:=string.TrimSpace(str2 string)//string.TrimSpace()会将str2的\n\t\r全部剪去,只剩下可输出的字符串
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF {
break
} //错误处理
fmt.Println(line) //输出
}
//2.2bufio.ReadString()
file, err = os.Open("tmp/dat.txt") //os.open()创建句柄
check(err)
r = bufio.NewReader(file) //bufio.NewReader()将句柄生成reader
for {
line, err := r.ReadString('\n') //reader.ReadString()读取一行
line = strings.TrimSpace(line) //修剪line
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF {
break
} //错误处理
fmt.Println(line) //输出
}
//reader.ReadBytes()返回的是[]byte,而reader.ReadString()返回的是string
//3每次读取固定字节数
//不是所有的文件都有换行符\n
//那么对于不换行的大文件来说怎么处理呢
//3.1使用os库
//具体做法:1 使用os.Open()创建句柄,2 使用bufio.NewReader()创建Reader,3 在for循环内调用Reader的Read函数,每次仅读取固定字节数量的数据
file, err = os.Open("tmp/dat.txt")
check(err)
r = bufio.NewReader(file)
buf := make([]byte, 1024) //临时存储每次得到的字节(1024个)
for {
n, err := r.Read(buf) //返回的n是每次读取到的字节数目,可能小于len(buf)
if err != io.EOF && err != nil {
panic(err)
}
if n == 0 {
break
} //读完了
fmt.Println(buf[:n]) //读多少输出多少,不把buf后面的默认值也输出出来
}
//在使用os库每次读取特定字节时,我们不用将buf[]byte数组转化为string
//3.2使用syscall库
//os库本质上也是在调用syscall库,使用syscall过于底层,一般不使用
b3 := make([]byte, 2)
n3, err := io.ReadAtLeast(file, b3, 2)
check(err)
fmt.Println("size =", n3, ",b3 =", b3)
_, err = file.Seek(0, io.SeekStart) //回转
check(err)
}
上述代码中出现了函数reader.ReadString()和strings.TrimSpace()和reader.Read(),解释如下:
函数定义:func (b *Reader) ReadString(delim byte) (string, error)
delim:读取的结束字符,一般为“\n”
功能:读取一行
函数定义:func TrimSpace(s string) string
功能:用空格替代\t\r\n
函数定义:func (b *Reader) Read(p []byte) (n int, err error)
功能:按p数组的len读取字符到p数组中,n为实际读到的字符数,返回io.EOF(读到文件结尾了)或nil(啥也没读到)
5 写文件
5.1 file.Write()
函数定义:
func (f *File) Write(b []byte) (n int, err error)
使用注意:使用之前先要判断文件是否存在
具体判断代码:
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取path下的文件信息
// func Stat(name string) (FileInfo, error)
if err == nil || (err != nil && os.IsExist(err)) {
return true
}
return false
}
5.2 io.WriteString()
函数定义:func WriteString(w Writer, s string) (n int, err error)
代码示例:
package main
import (
"fmt"
"io"
"os"
)
const strs = "\n \n 写文件ok思密达3"
//strs是待写入的字符串
func main() {
//func WriteString(w Writer(对象), s string) (n int(写入的字节数), err error)
fmt.Println("golang写文件")
var (
fileName = "./tmp/2.txt"
//./表示project的路径,是一种代替
content = strs
file *os.File //创建句柄类型file变量
err error
) //变量集合
//使用io.WriteString()之前先判断文件是否存在
if Exists(fileName) { //当文件存在
file, err = os.OpenFile(fileName, os.O_APPEND, 0666)
//os.Open()是只读模式的os.OpenFile()若要写文件则用os.OpenFile(),但要记得用defer file.Close()关闭文件以释放资源
if err != nil {
fmt.Println("打开文件错误:", err)
return
}
fmt.Println("打开文件成功")
} else { //文件不存在
file, err = os.Create(fileName) //创建文件
if err != nil {
fmt.Println("创建文件失败:", err)
return
}
fmt.Println("创建文件成功")
}
defer file.Close() //要记得fileinfo需在函数执行完后关闭
//写文件
n, err := io.WriteString(file, content)
if err != nil {
fmt.Println("写入文件错误:", err)
return
}
fmt.Println("写入文件成功,n =", n)
//读取文件
filecontent, err := os.ReadFile(fileName)
if err != nil {
fmt.Println("读取错误:", err)
return
}
fmt.Println(string(filecontent))
}
// 判断所给路径文件是否存在
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取path下的文件信息
// func Stat(name string) (FileInfo, error)
if err == nil || (err != nil && os.IsExist(err)) {
return true
}
return false
}
5.3 ioutil.WriteFile()
函数定义:func WriteFile(filename string, data []byte, perm fs.FileMode) error
使用注意:用之前先判断文件是否存在
代码示例:
//func WriteFile(filename string, data []byte, perm os.FileMode) error
//perm 文件权限 data 要写入的内容
//使用 ioutil.WriteFile写文件,在写入文件之前,我们不需要判断文件是否存在,如果文件不存在,会自动创建文件,如果文件存在,则会覆盖原来的内容
package main
import (
"fmt"
"io/ioutil"
)
const strs1 = "\n \n 完美世界 (石昊)"
func main() {
var (
fileName = "./tmp/3.txt"
content = strs1
err error
)
//写入文件
if err = ioutil.WriteFile(fileName, []byte(content), 0777); err != nil {
fmt.Println("写入错误:", err)
return
}
//读取文件
fileContent, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Println("读取错误:", err)
return
}
fmt.Println("读取成功,文件内容:", string(fileContent))
}
5.4 file.WriteString()
函数定义:func (f *File) WriteString(s string) (n int, err error)
注意:使用前先判断文件是否存在
与io.WriteString()区别:
n,err =io.WriteString(file,content)
n,err =file.WriteString(content)
6 其他有关文件的函数
6.1 os.Stat()
函数定义:func Stat(path string) (FileInfo, error)
6.2 bufio.NewReader()
函数定义:func NewReader(rd io.Reader) *Reader
函数功能:传入*file,返回*Reader
文末声明:时间有限,关于go语言文件的操作还不够详尽,日后可能会补充
有关go的各种包内的函数的详细解释请前往官网pkg.go.dev/搜索