上图
创建文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create(`E:\Code\moose-workspace\go-lean\input_output\demo.txt`)
if err != nil {
fmt.Println("文件创建失败")
fmt.Println(err)
return
}
defer file.Close()
}
-
在 golang 中,创建文件,使用 os 包
-
os.Create(name string) 创建文件,指定存储文件磁盘路径
-
指定相对路径:比如 "./demo.txt" 会在当前项目根路径下创建文件,指定磁盘路径会在自定位置创建
-
如果磁盘路径不存在,创建文件会失败,报错
因为 E:\Code\moose-workspace\go-lean\input 这个目录是没有的
open E:\Code\moose-workspace\go-lean\input\demo.txt: The system cannot find the path specified.
-
-
defer 推迟的意思吧,
关键字file.Close() 文件读写完,把文件流关闭,避免资源浪费 -
运行之后,会在指定的位置看到这个文件 ~
创建目录
path := `E:\Code\moose-workspace\go-lean\input`
if _, err := os.Stat(path); os.IsNotExist(err) {
os.Mkdir(path, os.ModePerm)
}
- 在文件目录不存在则创建文件目录
os.Stat判断文件是否存在os.IsNotExist(err)Stat 文件不存在,会抛出一个异常,判断异常os.Mkdir创建目录,指定访问权限- 这个时候再去写文件都是OK的
查看返回值
在学习的时候,通常不知道返回什么类型,可以点击对应的方法去看源码
-
发现这个返回一个文件对象和一个错误对象
-
File 表示打开的文件描述符。
-
error 是 go 中内建错误
从 os.Create() 学到
- go 中的函数返回值,可以返回多个参数,返回的参数需要和返回值类型对应上
- 查看了源码之后,发现 go lang 中很多返回都是这样返回的
定义一个函数
func GetUserInfo(userid int) (name string, avatar string, age int) {
if userid == 10001 {
return "测试用户", "https://gitee.com/shizidada/moose-resource/raw/master/default-avatar.png", 10
}
return "", "", 0
}
- 这个方法是模拟根据用户 id 获取用户信息,返回多个值
- 只有 userid 匹配时才会返回
调用
...
name, avatar, age := GetUserInfo(10001)
fmt.Printf("姓名 %s 头像 %s 年龄 %d", name, avatar, age)
...
- 没有匹配会返回空
os.Open os.Create 区别
-
Open 打开文件,只有只读权限 O_RDONLY
-
Create 创建文件,读写,创建,清空权限 O_RDWR|O_CREATE|O_TRUNC
写文件
Create 的时候,返回了file 文件标识符,可以用这个去写文件了
file.WriteString("哈哈哈,写入文字")
file.Write([]byte("哈哈哈,byte 写入"))
读文件
...
fileinfo, err := os.Stat(filename)
filesize := fileinfo.Size()
file, err = os.Open(filename)
buf := make([]byte, filesize)
count := 0
for {
count, err = file.Read(buf)
if err == io.EOF {
fmt.Println("end ...")
break
}
fmt.Print(string(buf[:count]))
}
...
- for 循环读取文件
- file.Read 需要传递一个缓冲区
- 通过 os.Stat 可以获取文件的大小,构建一个缓冲区 buf
- 读完文件,会抛出一个 EOF 错误,需要手动判断这个错误
- string(buf[:count] 将 byte 转化为字符串
结合终端输入操作文件
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// 用常量来表示,不变的量
// 目录文件夹磁盘路径
const (
FOLDERPATH = `E:\Code\moose-workspace\go-lean\input_output2`
)
func BuildNote() {
// 输出提示
fmt.Println("请输入文件")
// bufio 创建 NewScanner
// os.Stdin 标准输入
input := bufio.NewScanner(os.Stdin)
// 等待输入
input.Scan()
// 获取控制台输入文本内容
filename := input.Text()
// 字符串判断,以 .txt 结尾
if !strings.HasSuffix(filename, ".txt") {
fmt.Println("文件名输入不正确")
return
}
// 拼接文件名字路径
filename = fmt.Sprintf(`%s\%s`, FOLDERPATH, filename)
// 使用 os.Create 创建文件
file, err := os.Create(filename)
if err != nil {
fmt.Println("文件创建失败")
return
}
// defer 推迟关闭文件流
defer file.Close()
// 控制台输入
fmt.Println("输入标题")
input = bufio.NewScanner(os.Stdin)
input.Scan()
// title 拼接一个换行符
title := fmt.Sprintf("%s\n", input.Text())
// 具体输出内容
fmt.Println("请输入内容")
input = bufio.NewScanner(os.Stdin)
// 用来保存输入的内容
contents := make(map[string]int)
// for 循环,使控制台在按回车键之后不中断
for {
input.Scan()
content := input.Text()
content += "\n"
// 判断输入内容是否为 exit,退出控制台输入
if strings.Contains(content, "exit") {
break
}
// 输入的内容,追加到 contents 中
contents[content]++
}
// bufio 创建 NewWriter,用于写文件
w := bufio.NewWriter(file)
w.WriteString(title)
// 遍历 contents,拿到出入的内容
for line := range contents {
// 写入
w.WriteString(line)
}
// 刷新缓冲,写到文件中
w.Flush()
}
func main() {
// 构建函数
BuildNote()
}
知识点
-
使用 bufio 封装了文件 I\O,方便操作
-
fmt.XXX fmt 常用包,输出
-
make(map[string]int) 开辟一个切片
-
for line :=
rangecontents;range 遍历切片 -
w.WriteString 之后需要 w.Flush,不调用 文件不会写入到文件中
-
strings.XXX,调用 strings 包中封装判断字符串函数,还有很多,参考