golang学习笔记之文件操作
golang学习笔记之文件操作基本介绍文件的基本操作打开和关闭文件读文件操作应用写文件操作的应用判断文件或目录存在拷贝文件文件编程应用
基本介绍
文件在程序中是以流的形式来操作的
流:数据在数据源(文件)和程序(内存P)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径(读)
输出流:数据从程序(内存)到数据源(文件)的路径 (写)
os.File封装所有文件相关的操作,File是一个结构体
文件的基本操作
打开和关闭文件
bogon:basic xushuo$ go run main.go
open file err= open Volumes/data/app/jump.txt: no such file or directory
file=<nil>
close file err= invalid argument
bogon:basic xushuo$ go run main.go
file=&{0xc000092180}package main
import (
"fmt"
"os"
)
func main() {
//打开文件
//概念说明:file的叫法
//1. file对象
//2. file指针
//3. file文件句柄
file, err := os.Open("/Volumes/data/app/jump.txt")
if err != nil {
fmt.Println("open file err=", err)
}
//输出文件内容
fmt.Printf("file=%v\n", file)
//关闭文件
err = file.Close()
if err != nil {
fmt.Println("close file err=", err)
}
}
---------------
bogon:basic xushuo$ go run main.go
open file err= open Volumes/data/app/jump.txt: no such file or directory
file=<nil>
close file err= invalid argument
bogon:basic xushuo$ go run main.go
file=&{0xc000092180}
输出下的文件是一个指针。引用类型
读文件操作应用
- 读取文件的内容并显示在终端(带缓冲区的方式),使用os.Open,file,Close,bufio.NewReader*(),reader.ReadString函数和方法
package main
import (
"fmt"
"os"
"bufio"
"io"
)
func main() {
//打开文件
file, err := os.Open("/Volumes/data/app/jump.txt")
if err != nil {
fmt.Println("open file err=", err)
}
//代码执行到最后关闭文件
defer file.Close() //要及时关闭file句柄,否则会有内存泄漏
// 创建一个*Reader,是带缓冲区的
/*
const (
defaultBufSize = 4096 //默认缓冲区为4096
)
*/
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n') //读取一个换行就结束 双引号会报错
if err == io.EOF { //io,EOF表示文件的末尾
break
}
//输出文件内容
fmt.Printf(str)
}
fmt.Println("文件读取结束")
}
------------------
bogon:basic xushuo$ go run main.go
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA7KKh+j+17V+bwfvp95WS2s1rAkuUUmstsALZqUYoATuaBMLu
QFwmd7rLfIq7oQCn33iSJeb3ial2DAQIvlXOQW4liBNZPpqBZ4IiKvDUqqECGEv/
tVFUr9LJdLZtzhIA7l7QZ/3SC3EJybM8ZAPedgtdj2kIgjEsbh5IWQ==
-----END RSA PRIVATE KEY-----
文件读取结束
- 读取文件的内容并显示在终端(使用ioutil,一次将整个文件读取到内存中),这种方式适用于文件表达的情况,相关方法和函数(ioutil.ReadFile)
package main
import (
"fmt"
"io/ioutil"
)
func main() {
//使用ioutil。ReadFile一次性读取文件到内存
file := "/Volumes/data/app/jump.txt"
content, err := ioutil.ReadFile(file)
if err != nil {
fmt.Println("open file err=", err)
}
//读取到的内存显示在终端
fmt.Printf("%v", content) //显示[]byte
fmt.Printf("string-%v", string(content)) //显示字符串e
//我们没有显示的Open文件,因此也不需要显式的Close文件
//因为文件的Open和Close被封装到ReadFile函数内部
}
写文件操作的应用
使用os.OpenFile(), bufio.NewWriter(),*Writer的方法是一个带缓冲区的
- 创建一个新文件,写入内容 5句 "Hello Gardon"
package main
import (
"fmt"
"os"
"bufio"
)
func main() {
//创建一个新文件,写入内容 5句"Hello Gardon"
filePath := "/Volumes/data/app/ABC.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY| os.O_CREATE, 0666)
if err != nil {
fmt.Println("open file err=", err)
return
}
//准备写入5句"Hello Gardon"
str := "Hello Gardon\n"
//写入时,使用带缓存的*Writer
writer := bufio.NewWriter(file)
for i := 0 ; i < 5; i++ {
writer.WriteString(str)
}
//因为writer是带缓存,因为在调用WriteString方法是,其实内容是先写入到缓存的,
//所以需要调用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
- 打开一个存在的文件,在原来的内容覆盖成新的内容 10句 "你好! ABC "
package main
import (
"fmt"
"os"
"bufio"
)
func main() {
// 打开一个存在的文件,在原来的内容覆盖成新的内容 10句 "你好! ABC "
//打开已经存在的ABC文件 os.O_TRUNC 置空后重新写入新内容
filePath := "/Volumes/data/app/ABC.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY| os.O_TRUNC, 0666)
if err != nil {
fmt.Println("open file err=", err)
return
}
//准备写入5句"Hello Gardon"
str := "你好! ABC\r \n"
//写入时,使用带缓存的*Writer
writer := bufio.NewWriter(file)
for i := 0 ; i < 10; i++ {
writer.WriteString(str)
}
//因为writer是带缓存,因为在盗用WriteString方法是,其实内容是先写入到缓存的,
//所以需要嗲用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
- 打开一个存在的文件,在原来的内容追加内容 "ABC! ENGLISH"
package main
import (
"fmt"
"os"
"bufio"
)
func main() {
// 打开一个存在的文件,在原来的内容追加内容 "ABC! ENGLISH"
//打开已经存在的ABC文件 os.O_APPEND 追加
filePath := "/Volumes/data/app/ABC.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY| os.O_APPEND, 0666)
if err != nil {
fmt.Println("open file err=", err)
return
}
//准备写入5句"Hello Gardon"
str := "ABC! ENGLISH\r\n"
//写入时,使用带缓存的*Writer
writer := bufio.NewWriter(file)
for i := 0 ; i < 10; i++ {
writer.WriteString(str)
}
//因为writer是带缓存,因为在盗用WriteString方法是,其实内容是先写入到缓存的,
//所以需要嗲用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
- 打开一个存在的文件,将原来的内容读出显示在终端,并且追加5句 "Hello ,北京"
package main
import (
"fmt"
"os"
"bufio"
"io"
)
func main() {
// 打开一个存在的文件,将原来的内容读出显示在终端,并且追加5句 "Hello ,北京"
//打开已经存在的ABC文件 os.O_RDWR
filePath := "/Volumes/data/app/ABC.txt"
file, err := os.OpenFile(filePath, os.O_RDWR| os.O_APPEND, 0666)
if err != nil {
fmt.Println("open file err=", err)
return
}
//代码执行接受及时关闭
defer file.Close()
//将原来的内容读出显示在终端
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n')
if err == io.EOF {
break
}
//显示到终端
fmt.Println(str)
}
//准备写入5句"Hello ,北京"
str := "Hello ,北京\r\n"
//写入时,使用带缓存的*Writer
writer := bufio.NewWriter(file)
for i := 0 ; i < 5; i++ {
writer.WriteString(str)
}
//因为writer是带缓存,因为在盗用WriteString方法是,其实内容是先写入到缓存的,
//所以需要嗲用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
- 将一个文件的内容,写入到另外一个文件中
package main
import (
"fmt"
"io/ioutil"
)
func main() {
filePath1 := "/Volumes/data/app/ABC.txt"
filePath2 := "/Volumes/data/app/copyAbc.txt"
data, err := ioutil.ReadFile(filePath1)
if err != nil {
fmt.Printf("read file err=%v\n", err)
return
}
// func WriteFile(filename string, data []byte, perm os.FileMode) error
// 返回一个err 所以只要err变量接受即可
err = ioutil.WriteFile(filePath2, data, 0666)
if err != nil {
fmt.Printf("write file err=%v\n", err)
}
}
判断文件或目录存在
拷贝文件
文件编程应用
统计英文 数字空格和其他字符的数量
package main
import (
"fmt"
"os"
"bufio"
"io"
// "io/ioutil"
)
type CharCount struct {
ChCount int
NumCount int
SpaceCount int
OtherCount int
}
func main() {
// 思路: 打开一个文件,创建一个Reader
// 每读取一行,就去统计改行有多少个英文 数字 空格和其他字符
// 结果保存到一个结构体中
fileName := "/Volumes/data/app/ABC.txt"
file, err := os.Open(fileName)
if err != nil {
fmt.Printf("open file err=%v\n", err)
return
}
defer file.Close()
//创建一个Reader
reader := bufio.NewReader(file)
//定义CharCount结构体实例
var count CharCount
//开始循环读取fileName的内容
for {
str, err := reader.ReadString('\n')
if err == io.EOF { //读取到最后停止,调出for循环
break
}
//便利str,进行统计
for _, v := range str {
switch {
case v >= 'a' && v <= 'z':
fallthrough //穿透
case v >= 'A' && v <= 'Z':
count.ChCount++
case v >= ' ' || v <= '\t':
count.SpaceCount++
case v >= '0' && v <= '9':
count.NumCount++
default:
count.OtherCount++
}
}
}
fmt.Printf("字符个数%v, 数字个数%v,空格个数%v,其他字符个数%v\n",
count.ChCount, count.NumCount, count.SpaceCount, count.OtherCount)
}
-----------------
bogon:basic xushuo$ go run main.go
字符个数157, 数字个数0,空格个数156,其他字符个数0