Go 文件操作
#### Go 文件操作
文件在程序是以流的形式操作的, 在Python,JAVA,Go ... 都一样;
流: 数据在数据源和程序之间经过的路径
输入流: 数据从数据源到程序的路径
输出流: 数据从程序到数据源的路径
下面来学习一下在Go中如何操作文件;
os.File 封装了所有文件相关的操作,File 是一个结构体,有很多方法
##### 打开和关闭文件
package main import ( "fmt" "os" ) func main(){ // 打开文件 // 默认返回两个值 // 第一个为file 对象,也可称为file 指针 // 第二个为错误信息,如果有错误,则err != nil file,err := os.Open("./test.txt") if err != nil { fmt.Println("open file error") fmt.Println(err) return } // 正常情况下打开文件后,file 实际上是一个指针,类型为*File fmt.Printf("file=%v",file) // 正常操作完文件后需要手动关闭文件,避免内存泄漏 err = file.Close() if err != nil { fmt.Println("close file error") } }
##### 读取文件
package main import ( "bufio" "fmt" "io" "io/ioutil" "os" ) func main(){ // 打开文件 // 默认返回两个值 // 第一个为file 对象,也可称为file 指针 // 第二个为错误信息,如果有错误,则err != nil file,err := os.Open("./test.txt") if err != nil { fmt.Println("open file error") fmt.Println(err) return } // 正常情况下打开文件后,file 实际上是一个指针,类型为*File fmt.Printf("file=%v\n",file) // 正常操作完文件后需要手动关闭文件,避免内存泄漏 defer file.Close() // 第一种方式: 带缓冲方式读取文件 reader := bufio.NewReader(file) //var content []byte for { //1. 一行一行读取 str,err := reader.ReadString('\n') //2. 带缓冲读取 //buf := make([]byte,1024) //n,err := reader.Read(buf) //content = append(content,buf[:n]...) if err == io.EOF { break } fmt.Print(str) } fmt.Println("file read end...") // 第二种方式: 一次性读取所有文件内容 // 适用于文件内容不大的情况 // ioutil.ReadFile 返回两个值,一个是读取到的内容字节切片, // 一个是返回的错误信息 content,err := ioutil.ReadFile("test.txt") if err != nil { fmt.Println(err) return } fmt.Println(string(content)) // ioutil.ReadFile 不需要显示的close 文件, open 和 close 方法被封装在ReadFile 内部 }
##### 写文件
关于打开文件指定选择,可以自行测试,特别是O_APPEND,O_TRUNC 使用较多;
package main import ( "bufio" "fmt" "os" ) func main(){ // os.OpenFile 是一个更为通用的函数,它需要三个参数, // 1. 文件路径 // 2. 指定选项,以下选项可组合使用 //O_RDONLY int = syscall.O_RDONLY // 以只读方式打开文件 //O_WRONLY int = syscall.O_WRONLY // 以只写方式打开文件 //O_RDWR int = syscall.O_RDWR // 以读写模式打开文件 //O_APPEND int = syscall.O_APPEND // 以写操作时将内容追加到文件末尾 //O_CREATE int = syscall.O_CREAT // 如果文件不存在,则创建新的文件 //O_EXCL int = syscall.O_EXCL // 和O_CREATE 一起使用,文件必须不存在 //O_SYNC int = syscall.O_SYNC // 打开文件以同步I/O //O_TRUNC int = syscall.O_TRUNC // 如果可能,打开文件时清空文件 // 3. 文件模式 // linux r=4,w=2,x=1 file,err := os.OpenFile("./abc.txt",os.O_WRONLY| os.O_CREATE,0666) if err != nil { fmt.Println("file open error") return } defer file.Close() writer := bufio.NewWriter(file) for i := 0;i<5;i++{ writer.WriteString("hello,golang\n") } // bufio.NewWriter 是带缓冲的写,如果不调用Flush 方法, 那么数据不会写入文件 writer.Flush() }
##### 判断文件是否存在
Go 中判断文件或文件夹是否存在的方法为使用os.Stat() 函数返回的错误值进行判断
1. 如果返回的错误为nil ,说明文件或文件夹存在
2. 如果返回的错误类型使用os.IsNotExist() 判断为true, 说明文件或文件夹不存在
3. 如果返回的错误为其它类型, 则不确定是否存在
func PathExists(path string)(bool,error) { _,err := os.Stat(path) if err != nil { if os.IsNotExist(err) { return false,nil } return false,err } return true,nil }
##### 文件复制
package main import ( "bufio" "fmt" "io" "os" ) func copyFile(srcFileName,destFileName string)(int64,error){ srcFile,err := os.Open(srcFileName) if err != nil { return 0,err } defer srcFile.Close() reader := bufio.NewReader(srcFile) destFile,err := os.OpenFile(destFileName,os.O_CREATE|os.O_WRONLY,0666) if err != nil { return 0,err } writer := bufio.NewWriter(destFile) defer destFile.Close() n,err := io.Copy(writer,reader) // 如果不调用 Flush 将会出现目标文件没有内容 writer.Flush() return n,err } func main(){ _,err := copyFile("./a.jpg","./b.jpg") if err != nil { fmt.Println("copy file error") fmt.Println(err) return } fmt.Println("file copy finish") }
最新文章会在个人微信公众号上同步更新,欢迎关注,大家一同交流学习
每天进步一点点!加油