文章目录
- 文件操作
- 打开文件
- 文件读取
- 写文件
- 判读文件或文件夹是否存在
- 拷贝文件
- 统计文件字符
- 命令行参数
- flag包解析命令行参数
文件操作
os.File
封装所有文件相关操作,File是一个结构体
打开文件
package mainimport ("fmt""os"
)func main() {file,err:=os.Open("test/test.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)}}//open file err= open test.txt: The system cannot find the file specified.
// file=<nil>
// close file err= invalid argument//自行创建文件之后
//file=&{0xc0000c2780}
文件读取
package mainimport ("bufio""fmt""io""os"
)func main() {file,err:=os.Open("test/test.txt")if err!=nil{fmt.Println("open file err=",err)}defer file.Close()reader:=bufio.NewReader(file)for{str,err:=reader.ReadString('\n')fmt.Print(str)if err==io.EOF{//io.EOF表示文件的末尾break}}fmt.Println()fmt.Println("文件读取结束。。。")
}
//123
//123
//文件读取结束。。。
使用ioutil一次将整个文件读入内存中,这种方法适用于文件不大的情况
package mainimport ("fmt""io/ioutil"
)func main() {content,err:=ioutil.ReadFile("test/test.txt")if err!=nil{fmt.Printf("read file err=%v\n",err)}fmt.Println(content)//[]bytefmt.Printf("%v",string(content))}
//[49 50 51 13 10 49 50 51]
//123
//123
写文件
package mainimport ("bufio""fmt""os"
)func main() {file,err:=os.OpenFile("test/a.txt",os.O_WRONLY | os.O_CREATE,0666)if err!=nil{fmt.Printf("open file err=%v",err)return}defer file.Close()str:="hello,world!\n"writer:=bufio.NewWriter(file)for i:=0;i<5;i++{writer.WriteString(str)}//先写到缓存,需要调用Flush方法,将缓冲的数据真正写入到文件中,否则文件没有数据writer.Flush()
}
示例:将一个文件的内容写入到另一个文件
注意:这两个文件都已经存在了
package mainimport ("fmt""io/ioutil"
)func main() {content1,err:=ioutil.ReadFile("test/a.txt")if err!=nil{fmt.Printf("read file err=%v",err)return}err2:=ioutil.WriteFile("test/b.txt",content1,0666)if err2!=nil{fmt.Printf("write file err=%v",err)}
}
判读文件或文件夹是否存在
os.Stat()
函数返回的错误值
- nil,文件或文件夹存在
- os.IsNotExist()判断为true,说明文件夹不存在
- 如果返回的错误为其他类型,不确定是否存在
package mainimport ("fmt""os"
)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
}func main() {paths:=[]string{"test/test.go","test/a.txt","test/test/"}for _,v:=range paths{b,e:=PathExists(v)fmt.Printf("bool=%v,err=%v\n",b,e)}}
//bool=false,err=<nil>
//bool=true,err=<nil>
//bool=false,err=<nil>
拷贝文件
// filecopy.go
package mainimport ("fmt""io""os"
)func main() {CopyFile("target.txt", "source.txt")fmt.Println("Copy done!")
}func CopyFile(dstName, srcName string) (written int64, err error) {src, err := os.Open(srcName)if err != nil {return}defer src.Close()dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)if err != nil {return}defer dst.Close()return io.Copy(dst, src)
}
统计文件字符
package mainimport ("bufio""fmt""io""os"
)type CharCount struct {ChCount int//英文个数NumCount int//数字个数SpaceCount int//空格个数OtherCount int//其他字符个数
}func main() {
// 打开文件,创建Reader,
// 每读取一行,就去统计该行有多少个英文、数字、空格和其他字符fileName:="test/file_IsExist.go"file,err:=os.Open(fileName)if err!=nil{fmt.Printf("open file err=%v\n",err)return}defer file.Close()var cout CharCountreader:=bufio.NewReader(file)
// 循环读取for{str,err:=reader.ReadString('\n')if err == io.EOF{break}//为了兼容中文字符,可以将str转成[]rune//str=[]rune(str)for _,v:=range str{switch {case v>='a' && v<='z':fallthrough//穿透case v>='A' && v<='Z':cout.ChCount++case v==' ' && v=='\t':cout.SpaceCount++default:cout.OtherCount++}}}fmt.Println(cout)
}
//{227 0 0 146}
命令行参数
os.Args
是一个string的切片,用来存储命令行参数
//file_args.go
package mainimport ("fmt""os"
)func main() {fmt.Println("命令行参数数量:",len(os.Args))for i,v:=range os.Args{fmt.Printf("args[%v]=%v\n",i,v)}
}
先编译,后执行
flag包解析命令行参数
前面的方法是比较原生的方式,解析参数不是特别的方便,特别是带有指定参数形式的命令行
flag包,可以更加方便的解析命令行参数,而且参数顺序可以随意
//file_flag.go
package mainimport ("flag""fmt"
)func main() {var user stringvar pwd stringvar host stringvar port int//&user接收用户命令行中的输入-u后面的参数值//"u",就是-u的指定参数//"", 默认值//"用户名,默认为空", 说明flag.StringVar(&user,"u","","用户名,默认为空")flag.StringVar(&pwd,"pwd","","密码,默认为空")flag.StringVar(&host,"h","localhost","主机名,默认为localhost")flag.IntVar(&port,"port",3306,"端口号,默认为3306")//这里有一个非常重要的操作,转换,必须调用这个方法flag.Parse()fmt.Printf("user=%v, pwd=%v, host=%v, port=%v\n",user,pwd,host,port)
}