文件
文件在程序中是以流的形式来操作的。
流: 数据在数据源(文件]和程序(内存)之间经历的路径
输入流: 数据从数据源(文件)到程序(内存)的路径
输出流: 数据从程序(内存)到数据源(文件)的路径
打开文件、关闭文件实例
package main
import (
"fmt"
"os"
)
func main(){
//概念说明: file 的叫法
//1. file叫file对象
//2. file叫file指针
//3. file叫file文件 句柄
//打开文件
file , err := os.Open("C:/Users/Hey/Desktop/a.txt")
if err != nil {
fmt.Println("open file err =",err)
}
//输出文件里面
fmt.Printf("file=%v",file)
//关闭文件
err=file.Close()
if err != nil {
fmt.Println("close file err =",err)
}
}
读文件操作应用实例
1) 读取文件的内容并显示在终端(带缓冲区的方式),使用os.Open, file.Close, bufio.NewReader().reader.ReadString 函数和方法.
//当函数退出时,要及时关闭file
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.Print(str)
}
fmt.Println("读取结束了")
2) 读取文件的内容并显示在终端(使用ioutil一次将整个文件读入到内存中),这种方式适用于文件不大的情况。相关方法和函数(ioutil.ReadFile)
//使用ioutil 一次性读所有
file := "C:/Users/Hey/Desktop/a.txt"
content, err := ioutil.ReadFile(file)
if err != nil{
fmt.Printf("read file err=%v",err)
}
//把读取到的内容显示到终端
//fmt.Printf("%v",content) //[]byte
fmt.Printf("%v",string(content))
//因为,我们没有显示的open文件,因此也不需要显示的close文件
写入文件
使用OpenFile
func OpenFile(name string, flag int, perm Filemode) (file *File, err error)
OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
第二个参数 flag int
第三个参数 perm Filemode(windows操作系统上无效)
写入文件实例
第一个实例
导入的包
filePath := "C:/Users/Hey/Desktop/b.txt"
//第三个参数在window下无效
file,err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE,0646)
if err !=nil {
fmt.Printf("open file err=%v \n",err)
return
}
//及时关闭file
defer file.Close()
//写入
str := "you are you are \n"
//写入时,使用带缓存的 *Writer
writer := bufio.NewWriter(file)
for i:=0;i<5;i++{
writer.WriteString(str)
}
//因为writer是带缓存,因此在调用Writerstring方法时,其实
//内容是先写入到缓存的,所以需要调用Flush方法,将缓冲的教据
//真正写入到文件中,否则文件中会没有数据!
writer.Flush()
第二实例
编程一个程序,将一个文件的内容,写入到另外一个文件。注:这两个文件已经存在了.
file1Path := "C:/Users/Hey/Desktop/b.txt"
file2Path := "C:/Users/Hey/Desktop/a.txt"
data,err := ioutil.ReadFile(file1Path)
if err !=nil {
fmt.Printf("read file err=%v \n",err)
return
}
err = ioutil.WriteFile(file2Path,data,0636)
if err !=nil {
fmt.Printf("Writer file err=%v \n",err)
return
}
判断文件是否存在
判断文件或文件夹是否存在的方法为使用os.Stat()函数返回的错误值进行判断:
1) 如果返回的错误为nil,说明文件或文件夹存在
2) 如果返回的错误类型使用os.IsNotExist()判断为true,说明文件或文件夹不存在
3) 如果返回的错误为其它类型,则不确定是否在存在
func PathExists(path string) (bool,error){
_,err := os.Stat(path)
if err == nil {
//文件或者目录存在
return true,nil
}
if os.IsNotExist(err){
return false ,nil
}
return false ,err
}
flag, _ := PathExists(file1Path)
if flag {
fmt.Println("存在")
}
拷贝文件
//接收两个文件路径
//srcFileName 源文件
//dstFileName 要拷贝的路径或文件,有可能不存在
func CopyFile(dstFileName string,srcFileName string) (written int64,err error){
srcFile, err := os.Open(srcFileName)
if err != nil{
fmt.Printf("open file err=%v\n",err)
}
defer srcFile.Close()
//通过srcFile ,获取到Reader
reader := bufio.NewReader(srcFile)
//打开dstFileName
dstFile,err :=os.OpenFile(dstFileName,os.O_WRONLY|os.O_CREATE,0666)
if err != nil{
fmt.Printf("open file err=%v\n",err)
}
//通过dstFile ,获取到Writer
writer := bufio.NewWriter(dstFile)
defer dstFile.Close()
return io.Copy(writer,reader)
}
srcFileName := "C:/Users/Hey/Desktop/2.jpg"
dstFileName := "D:/2.jpg"
_,err := CopyFile(dstFileName,srcFileName)
if err == nil{
fmt.Println("拷贝完成")
}else{
fmt.Printf("拷贝错误 err=%v",err)
}
统计一个文件中含有的英文、数字、空格及其它字符数量。
package main
import (
"fmt"
"os"
"bufio"
"io"
)
//用于保存统计结果
type CharCount struct{
EnCount int //英文个数
NumCount int //数字的个数
SpaceCount int //空格个数
OtherCount int //其他字符的个数
}
func main(){
//思路:打开一个文件,创一个Reader
//每读取一行,就去统计该行有多少个英文、数字、空格和其他字符
//然后将结果保存到一个结构体
filePath := "C:/Users/Hey/Desktop/b.txt"
file,err := os.Open(filePath)
if err!= nil{
fmt.Printf("open file err=%v\n",err)
return
}
defer file.Close()
//定义CharCount实例
var count CharCount
//创建一个Reader
reader := bufio.NewReader(file)
//开始循环的读取fileName的内容
for{
str,err := reader.ReadString('\n')
if err == io.EOF{ //读到文件末尾就退出
break
}
str=[]rune(str)
//遍历
for _,value := range str{
switch {
case value >= 'a' && value <= 'z':
fallthrough //穿透
case value >= 'A' && value <= 'Z':
count.EnCount++
case value >= ' ' || value <= '\t':
count.SpaceCount++
case value >= '0' && value <= '9':
count.NumCount++
default :
count.OtherCount++
}
}
}
//输出统计的结果
fmt.Printf("字符个数为=%v,数字的个数为=%v,空格的个数为=%v,其他字符个数=%v",
count.EnCount,count.NumCount,count.SpaceCount,count.OtherCount)
}