读取
读取-只读模式
此模式仅可读取文件
// 只读打开
f, err := os.Open("./book.html")
if err != nil {
fmt.Println(err.Error())
}
// 延迟关闭文件句柄
defer f.Close()
readFile := func() []byte {
// 读取文件内容
var content []byte
tmp := make([]byte, 128) // 临时变量
for {
// 读取值到临时变量
// byteNum 读取到的字节数
byteNum, err := f.Read(tmp)
if err == io.EOF {
fmt.Println("文件读取结束")
break
}
// 这里如果使用tmp[]..., 可以会写入零值数据(因为临时存储区大小和文件结尾可能不一致)
content = append(content, tmp[:byteNum]...)
}
return content
}
fmt.Printf("文件内容: \n%s\n", readFile())
虽然叫只读模式
,但是方法内调用的是OpenFile(name, O_RDONLY, 0)
,详见👇🏻
�
读取-通用模式
此模式是可自由设置执行的操作
及文件权限
等
常用flag:
变量 | 作用 |
---|---|
os.O_RDONLY | 只读模式 |
os.O_WRONLY | 只写模式 |
os.O_RDWR | 读和写模式 |
os.O_APPEND | 插入模式 |
os.O_CREATE | 创建模式(未找到文件会创建) |
os.O_SYNC | 同步IO模式(阻塞模式) |
os.O_EXCL | 与O_CREATE一起使用,文件不能存在 |
多模式 | os.O_WRONLY | os.O_CREATE |
// filename 文件名
// flag: 执行的操作(os/file.go 73行定义)
// filemode: 文件权限(仅在linux及类linux平台使用, os/types.go 35行定义 )
f, err := os.OpenFile("./deme.pu", os.O_RDONLY, os.ModePerm)
if err != nil {
fmt.Println(err.Error())
}
defer f.Close()
fmt.Printf("%s\n", readFile(f))
使用bufio
读取文件
f, err := os.Open("./demo.txt")
if err != nil {
fmt.Println(err.Error())
}
defer f.Close()
reader := bufio.NewReader(f)
for {
line, isPrefix, err := reader.ReadLine()
if err == io.EOF {
fmt.Println("文件读完了")
break
}
if err != nil {
fmt.Printf("文件读取失败%s\n", err.Error())
return
}
fmt.Println(string(line), isPrefix)
}
bufio
是在file的基础上封装了一层API,并且支持更多功能,比如上面代码会删除换行符
使用ioutil
读取整个文件
f, err := ioutil.ReadFile("./test.txt")
if err != nil {
log.Fatalln(err.Error())
}
fmt.Println(string(f))
ioutil.ReadFile()
方法可以将整个文件读取至变量,建议在读取小文件时使用(大文件容易造成内存泄露)
写入
f, _ := os.OpenFile("./deme.txt", os.O_WRONLY|os.O_CREATE, os.ModePerm)
defer f.Close()
byteNum, _ := f.Write([]byte("你好"))
fmt.Printf("write byte %d\n",byteNum)
以上代码使用os
包的OpenFile
函数,通过设置写入
和创建
flag来在文件没有时创建并写入文件
f, _ := os.OpenFile("./deme.txt", os.O_WRONLY|os.O_APPEND, os.ModePerm)
defer f.Close()
byteNum, _ := f.Write([]byte("你好"))
fmt.Printf("write byte %d\n",byteNum)
使用bufio.NewWriter
写入
f, _ := os.OpenFile("./demo.txt", os.O_WRONLY, os.ModePerm)
defer f.Close()
bfw := bufio.NewWriter(f)
bfw.Write([]byte("hello\n"))
bfw.WriteString("你好\n")
bfw.Flush()
使用bufio
可以将写入缓存中,然后通过Flush
方法写入文件
使用ioutil.WriteFile
写入
err := ioutil.WriteFile("./tmp.txt", []byte("world"), os.ModePerm)
if err != nil {
log.Fatalf("写入失败: %s", err.Error())
}
使用ioutil
同样可以写入文件,并且在文件不存在时帮你创建
使用ioutil.TmpDir
创建临时文件
name, _ := ioutil.TempDir("./tmp/", "dong_")
defer func(name string) {
err := os.Remove(name)
if err != nil {
log.Fatalln("删除失败")
} else {
log.Println("删除成功")
}
}(name)
fmt.Println(name)
time.Sleep(10 * time.Second)
临时目录可以临时存储一些文件,并在不再使用后删除
练习
写个cp
命令
var srcFile string
var dstPath string
_, err := fmt.Scan(&srcFile, &dstPath)
if err != nil {
log.Fatalln(err.Error())
return
}
src, err := os.Open(srcFile)
if err != nil {
log.Fatalf("Open file failed : %s", err.Error())
}
defer src.Close()
dst, err := os.OpenFile(dstPath+src.Name(), os.O_CREATE|os.O_EXCL|os.O_WRONLY, os.ModePerm)
if err != nil {
log.Fatalln(err.Error())
}
_, err = io.Copy(dst, src)
if err != nil {
log.Fatalf("Copy error %s", err.Error())
}
通过fmt.Scan
获取命令行参数,通过io.Copy
方法将流拷贝至新文件,因为os.OpenFile
实现了io.Writer
和io.Reader
接口