文件操读写作
主要有三个模块设计到了文件操作:os,bufio,ioutil。
打开文件:os.Openfile()、os.Open()、os.Create()
读写文件:无论使用os还是bufio模块进行读写,都需要先使用os模块打开文件
os:(直接对fd进行操作,读取操作可能会把多字节字符截断)
bufio:具有缓冲区,效率高。适合大文件读写。
ioutil无需事先打问文件,直接将整个文件拷贝到内存进行读写操作。适合小文件读写,例如配置文件。
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)
func method1() { //os模块
// 创建文件
// os.Create() 文件不存在则创建;文件存在则清空。
// 打开文件
//file, err := os.Open("./test.txt") // os.Open()打开的文件只能用于读取,不能用于写入,等同于os.OpenFile("./test.txt",O_RDONLY,0)
file, err := os.OpenFile("./t1.txt", os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666) // os.OpenFile()使用指定的模式(可以指定多种)和文件权限打开文件。
/*
指定模式:
os.O_RDONLY 只读
os.O_WRONLY 只写
os.O_RDWR 读写
os.O_CREATE 创建
os.O_APPEND 追加(默认从文件头开始写入)
os.O_TRUNC 清空
可以采用多种模式组合
os.O_WRONLY|os.O_CREATE 只写(从文件头开始写,会覆盖部分文件或全部文件)/新建
os.O_WRONLY|os.O_TRUNC|os.O_CREATE 只写(清空)/新建
os.O_RDWR|os.O_APPEND|os.O_CREATE 读写(追加)/新建
os.O_RDONLY 只读
*/
if err !=nil{
fmt.Println("文件打开失败:",err)
return
}
// 文件打开成功后的操作
defer file.Close()
//os模块
// 写
file.WriteString("浮世三千,吾爱有三\r\n日、月和你\r\n日为朝,月为暮,卿为朝朝暮暮\r\n")
file.Write([]byte("大河向东流\r\n天上的星星参北斗\r\n"))
file.sync() // 将文件系统缓冲区内容写入磁盘
// 读
file.Seek(0,0) // 修改读写位置:file.Seek(offset,io.SeekStart|io.SeekCurrent|io.SeekEnd),offset可为负数;返回值为相对文件头的偏移量
bytes := make([]byte, 128)
for {
n, err := file.Read(bytes) // 由于[]byte的长度是128,所以会从文件中读取128个字节保存到temp中。而且会发生字符的截断导致出现乱码。所以不适合读取文本,适合读取二进制数据。
if err==io.EOF{
fmt.Println("文件读取完毕")
return
}
if err!=nil{
fmt.Println("文件读取失败",err)
return
}
fmt.Println("读取文件字节数:",n)
fmt.Println(string(bytes))
}
}
func method2(){//bufio模块
// 打开文件
//file, err := os.Open("./test.txt") // os.Open()打开的文件只能用于读取,不能用于写入
file, err := os.OpenFile("./t2.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) // os.OpenFile()使用指定的模式和属主打开文件。
if err !=nil{
fmt.Println("文件打开失败:",err)
return
}
// 文件打开成功后的操作
defer file.Close()
//bufio模块
writer := bufio.NewWriter(file)
writer.WriteString("锄禾日当午\r\n")
writer.WriteString("汗滴禾下土\r\n")
writer.WriteString("谁知盘中餐\r\n")
writer.WriteString("粒粒皆辛苦\r\n")
writer.Flush() // 刷新缓冲区数据到文件中
file.Seek(0,0) // 将读/写的位置设置成文件开头,开始读取文件
reader := bufio.NewReader(file)
// 接下来,就从reader缓冲区中读取数据
for{
s, err := reader.ReadString('\n') // 读取到指定的分割符。指定字符处,类似ReadBytes()
if err==io.EOF{ // 错误的一种,文件读取完毕
fmt.Println("文件读取完毕")
return
}
if err!=nil {
fmt.Println("文件读取失败",err)
return
}
fmt.Print(s)
}
}
func method3(){//ioutil模块,ioutil.ReadFile()函数定义为一次性读取整个文件到内存,它不会将读取返回的EOF视为应报告的错误。此操作文件无需打开和关闭
//ioutil写文件
ioutil.WriteFile("./t3.txt",[]byte("I love three things in this world.\r\n" +
"Sun moon and you.\r\n" +
"Sun for morning. moon for night.\r\n" +
"and you forever.\r\n"),0666)
//ioutil读取文件
bytes, err := ioutil.ReadFile("./t3.txt")
if err!=nil{
fmt.Println("文件读取错误",err)
return
}
fmt.Println(string(bytes))
}
func main() {
fmt.Println("====os模块读写文件======")
method1()
fmt.Println("====bufio模块读写文件======")
method2()
fmt.Println("====ioutil模块读写文件======")
method3()
}
推荐示例:os.Openfile()打开文件;bufio读写文件
func main() {
filename := "./test.txt"
file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if err != nil {
fmt.Println("文件打开失败:", err)
return
}
//文件打开成功后的操作
defer file.Close()
// 写操作
writer := bufio.NewWriter(file)
writer.Write([]byte("hello\r\n"))
writer.WriteString("World\r\n")
writer.Flush()
// 读操作
file.Seek(0,io.SeekStart)
reader := bufio.NewReader(file)
for{
s, err := reader.ReadString('\n') // 读取到指定的分割符。指定字符处
if err==io.EOF{ // 错误的一种,文件读取完毕
fmt.Println("文件读取完毕")
return
}
if err!=nil {
fmt.Println("文件读取失败:",err)
return
}
fmt.Print(s)
}
}
目录也是一直特殊的文件,其内容称之为目录项。所以目录也使用os.OpenFile()函数进行打开操作。只不过需要注意的是打开模式为os.O_RDONLY,权限为os.ModeDir
func main() {
dirname := `d:\Users`
file, err := os.OpenFile(dirname, os.O_RDONLY, os.ModeDir)
if err != nil {
fmt.Println("目录打开失败:", err)
return
}
//文件打开成功后的操作
defer file.Close()
infos, err := file.Readdir(-1)
if err != nil {
fmt.Println("读取目录的目录项失败:",err)
return
}
for _, info := range infos {
if info.IsDir() {
fmt.Printf("%s 是个目录",info.Name())
}
}
}
func shell(path string, name string, arg ...string) {
cmd := exec.Command(name, arg...)
cmd.Dir = path
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Errorf("[Error]执行"+arg[0]+"操作失败:%s",string(out[:])+err.Error())
os.Exit(1)
}
}