文章目录
- 文件操作
- 打开文件
- 文件读取
- 写文件
- 判读文件或文件夹是否存在
- 拷贝文件
- 统计文件字符
- 命令行参数
- flag包解析命令行参数
 
文件操作
os.File封装所有文件相关操作,File是一个结构体
打开文件

package main
import (
	"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 main
import (
	"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 main
import (
	"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)//[]byte
	fmt.Printf("%v",string(content))
}
//[49 50 51 13 10 49 50 51]
//123
//123
写文件

package main
import (
	"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 main
import (
	"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 main
import (
	"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 main
import (
    "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 main
import (
	"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 CharCount
	reader:=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 main
import (
	"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 main
import (
	"flag"
	"fmt"
)
func main() {
	var user string
	var pwd string
	var host string
	var 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)
}





















