文件
流
数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
文件操作
package main
import (
"fmt"
"os"
)
func main() {
//打开文件
//概念说明:file 的叫法
//1. file 叫 file对象
//2. file 叫 file指针
//3. file 叫 file文件句柄
file, err := os.Open("d:/test.txt")
if err != nil {
fmt.Println(err)
}
//输出文件
fmt.Printf("file = %v", *file)
//关闭文件
err = file.Close()
if err != nil {
fmt.Println(err)
}
}
读文件操作应用案例
读取文件的内容并显示在终端(带缓冲区的方式),使用os.Open, file.Close,bufio.NewReader(), reader.Readstring函数和方法
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
//打开文件
//概念说明:file 的叫法
//1. file 叫 file对象
//2. file 叫 file指针
//3. file 叫 file文件句柄
file, err := os.Open("d:/test.txt")
if err != nil {
fmt.Println(err)
}
//关闭文件
defer file.Close() //及时关闭file,否则会有内存泄漏
//创建一个 *Reader,是带缓冲的
//const (
// defaultBufSize = 4096 //默认的缓冲区为4896
//)
reader := bufio.NewReader(file)
//循环读取文件内容
for {
str, err := reader.ReadString('\n') //读到换行就截止
if err == io.EOF { //io.EOF表示文件的末尾
break
}
//输出内容
fmt.Print(str)
}
fmt.Println("结束...")
}
读取文件的内容并显示在终端(使用ioutil一次将整个文件读入到内存中),这种方式适用于文件不大的情况。相关方法和函数(ioutil.ReadFile)
package main
import (
"fmt"
"io/ioutil"
)
func main() {
//使用ioutil.ReadFile一次性将文件读取到位
file := "d:/test.txt"
content, err := ioutil.ReadFile(file)
if err != nil {
fmt.Printf("read file %v", err)
}
//把读取到的内容显示到终端
fmt.Printf("%v", string(content)) //[]byte
//我们没有显示的open文件,因此也不需要显示的close
//因为文件的open和close被封装到readFile 函数内部
}
写入文件
1.创建一个新文件,写入内容 5句"hello,Gardon"
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//创建一个新文件,写入内容 5句"hello,Gardon"
//1. 打开文件 d:/abc.txt
filePath := "d:/abc.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("open file err = %v \n", err)
return
}
//及时关闭
defer file.Close()
//准备写入5句 "hello,Gardon"
str := "hello,Gardon \n"
//写入时,使用带缓存的 *Writer
writer := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
writer.WriteString(str)
}
//因为writer是带缓存的,因此在调用writerString方法时,其实内容是写入缓存的,
//所以需要调用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
2.打开一个存在的文件中,将原来的内容覆盖成新的内容10句 ”你好“
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//打开一个存在的文件中,将原来的内容覆盖成新的内容10句 你好
//1. 打开文件 d:/abc.txt
filePath := "d:/abc.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
fmt.Printf("open file err = %v \n", err)
return
}
//及时关闭
defer file.Close()
//准备写入5句 "hello,Gardon"
str := "你好 \n"
//写入时,使用带缓存的 *Writer
writer := bufio.NewWriter(file)
for i := 0; i < 10; i++ {
writer.WriteString(str)
}
//因为writer是带缓存的,因此在调用writerString方法时,其实内容是写入缓存的,
//所以需要调用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
3.打开一个存在的文件,在原来的内容追加内容 ABC
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//打开一个存在的文件,在原来的内容追加内容 ABC
//1. 打开文件 d:/abc.txt
filePath := "d:/abc.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
fmt.Printf("open file err = %v \n", err)
return
}
//及时关闭
defer file.Close()
//准备写入5句 "hello,Gardon"
str := "abc \n"
//写入时,使用带缓存的 *Writer
writer := bufio.NewWriter(file)
for i := 0; i < 10; i++ {
writer.WriteString(str)
}
//因为writer是带缓存的,因此在调用writerString方法时,其实内容是写入缓存的,
//所以需要调用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
4.打开一个存在的文件,将原来的内容读出显示在终端,并且追加5句 hello,北京!
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
//打开一个存在的文件,将原来的内容读出显示在终端,并且追加5句 hello,北京!
//1. 打开文件 d:/abc.txt
filePath := "d:/abc.txt"
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0666)
if err != nil {
fmt.Printf("open file err = %v \n", err)
return
}
//及时关闭
defer file.Close()
//读取原来的内容
reader := bufio.NewReader(file)
for {
str, err := reader.ReadString('\n')
if err == io.EOF {
break
}
fmt.Print(str)
}
//准备写入5句 "hello,Gardon"
str := "hello,北京!\n"
//写入时,使用带缓存的 *Writer
writer := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
writer.WriteString(str)
}
//因为writer是带缓存的,因此在调用writerString方法时,其实内容是写入缓存的,
//所以需要调用Flush方法,将缓冲的数据真正写入到文件中,否则文件中会没有数据
writer.Flush()
}
5.编程一个程序,将一个文件的内容,写入到另外一个文件。注。这两个文件已经存在了.说明:使用ioutil.ReadFile / ioutil.WriteFile完成写文件的任务.
package main
import (
"fmt"
"io/ioutil"
)
func main() {
//将d:/abc.txt文件内容导入到 d:/kkk.txt
//1.首先将 d:/abc.txt 内容读取到内存
//2.将读取到的内容写入 d:/kkk.txt
file1Path := "d:/abc.txt"
file2Path := "d:/kkk.txt"
data, err := ioutil.ReadFile(file1Path)
if err != nil {
//说明读取文件有错误
fmt.Printf("read file err = %v", err)
return
}
err = ioutil.WriteFile(file2Path, data, 0666)
if err != nil {
//说明写文件有错误
fmt.Printf("write file err = %v", err)
return
}
}
判断文件是否存在
拷贝文件
package main
import (
"bufio"
"fmt"
"io"
"os"
)
//自己编写一个函数,接收两个文件路径 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", err)
}
defer srcFile.Close()
//通过srcfile,获取到 Reader
reader := bufio.NewReader(srcFile)
//打开dsfilename
dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
//通过dstFile 获取到writer
writer := bufio.NewWriter(dstFile)
defer dstFile.Close()
return io.Copy(writer, reader)
}
func main() {
//将d:/1.jpg 拷贝到d:/abc.jpg
//调用CopyFile
srcFile := "d:/1.jpg"
dstFile := "d:/abc.jpg"
_, err := CopyFile(dstFile, srcFile)
if err == nil {
fmt.Println("拷贝完成")
}
}
案例
记录文件中的字母,数字,空格的个数
package main
import (
"bufio"
"fmt"
"io"
"os"
)
//定义一个结构体,用于保存统计结果
type CharCount struct {
ChCount int //记录英文个数
NumCount int //记录数字个数
SpaceCount int //记录空格个数
OtherCount int //记录其他的个数
}
func main() {
//思路:打开一个文件,创一个Reader
//每读取一行,就去统计该行有多少个英文、数字、空格和其他字符
//然后将结果保存到一个结构体
fileName := "d:/abc.txt"
file, err := os.Open(fileName)
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
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",
count.ChCount, count.NumCount, count.SpaceCount, count.OtherCount)
}
命令行参数
os.Args是一个string 的切片,用来存储所有的命令行参数
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("命令行的参数有", len(os.Args))
for i, v := range os.Args {
fmt.Printf("arg[%v] = %v\n", i, v)
}
}
flag包用来解析命令行参数
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")
flag.IntVar(&port, "port", 3306, "端口号,默认问3306")
//这里有一个非常重要的操作,转换,必须调用该方法
flag.Parse()
//输出结果
fmt.Printf("user = %v pwd = %v host = %v port = %v",
user, pwd, host, port)
}