Go语言基础(一)文件操作

本文主要介绍了Go语言中文件读写的相关操作。

关键词:golang

获得当前路径下的所有文件

1
2
3
4
5
6
7
8
filenames, err := ioutil.ReadDir("./")
if err != nil {
fmt.Printf("读取文件夹失败, 错误: %s", err.Error())
return
}
for _, file := range filenames {
fmt.Println(file.Name())
}

打开和关闭文件

只读打开

1
2
3
4
5
6
7
8
// 只读打开
file, err := os.Open("./main.go")
if err != nil {
fmt.Printf("打开文件失败, 错误: %s", err.Error())
return
}
defer file.Close() // defer注册文件关闭语句

读取文件

file.Read()

基本使用

函数原型

1
func (f *File) Read(b []byte) (n int, err error)

举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func main() {
file, err := os.Open("main.go")
if err != nil {
panic(err)
}
defer file.Close()
// 一次只能读128字节
var tmp = make([]byte, 128) // 开辟一个可以存放128字符的字节数组,存放读取的字符
n, err := file.Read(tmp) // n: 读数据的大小
if err == io.EOF {
fmt.Println("文件读完了")
return
}
if err != nil {
panic(err)
}
fmt.Printf("读取了%d个字符\n", n)
fmt.Println(string(tmp[:n]))
}


循环读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func main() {
file, err := os.Open("main.go")
if err != nil {
panic(err)
}
defer file.Close()
// 循环读取,每次读128
var content []byte
var tmp = make([]byte, 128) // 开辟一个可以存放128字符的字节数组,存放读取的字符
for {
n, err := file.Read(tmp) // n: 读数据的大小
if err == io.EOF {
fmt.Println("文件读完了")
break
}
if err != nil {
panic(err)
}

content = append(content, tmp[:n]...)
}
fmt.Println(string(content))
}

bufio

按行读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func main() {
file, err := os.Open("main.go")
if err != nil {
panic(err)
}
defer file.Close()
// bufio读取
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('\n') // 单引号, 返回string类型
if err == io.EOF {
if len(line) != 0 {
fmt.Println(line)
}
fmt.Println("文件读完了")
break
}
if err != nil {
panic(err)
}
fmt.Print(line)
}
}

ioutil.Readfile()

直接调用了函数Os.Readfile()

这个方式最简单粗暴,在不考虑性能的情况下可以直接用这种方式

1
2
3
4
5
6
7
8
func main() {
data, err := ioutil.ReadFile("main.go") // 返回[]byte类型
if err != nil {
panic(err)
}
fmt.Println(string(data))
}

文件写入

os.Openfile()以指定方式打开文件,实现文件写入

函数原型

1
func OpenFile(name string, flag int, perm FileMode) (*File, error)

打开文件的方式如下

方式 含义
O_RDONLY 只读方式打开文件
O_WRONLY 只写方式打开文件
O_RDWR 读写方式打开文件
O_APPEND 追加方式打开文件
O_CREATE 创建文件
O_EXCL 和O_CREATE配合使用,创建文件时文件必须不存在
O_SYNC 打开文件用于同步IO
O_TRUNC 打开文件时清空文件

Wirte和WirteString

1
2
3
4
5
6
7
8
9
10
func main() {
file, err := os.OpenFile("1.txt", os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
defer file.Close()
str := "HelloWorld"
file.Write([]byte(str)) // 写[]byte
file.WriteString(str) // 写string
}

Buffo.NewWirter

带缓冲的读写器

1
2
3
4
5
6
7
8
9
10
11
func main() {
file, err := os.OpenFile("1.txt", os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
defer file.Close()
writer := bufio.NewWriter(file)
str := "HelloWorld"
writer.WriteString(str) // 写string到缓存
writer.Flush() // 缓存刷入磁盘
}

ioutil.WriteFile()

直接调用os.WriteFile(filename, data, perm)

这种方式也是最简单粗暴

1
2
3
4
5
6
7
func main() {
str := "HelloWorld"
err := ioutil.WriteFile("1.txt", []byte(str), 0644)
if err != nil {
panic(err)
}
}

golang实现cat命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func cat(b *bufio.Reader) {
for {
buf, err := b.ReadString('\n') // 注意是字符
if err == io.EOF {
// 读完了
fmt.Fprintf(os.Stdout, "%s", buf)
break
}
fmt.Fprintln(os.Stdout, buf)
}
}

func main() {
flag.Parse() // 解析命令行参数
if flag.NArg() == 0 {
cat(bufio.NewReader(os.Stdin))
}
// 读取每个文件到终端
for i := 0; i < flag.NArg(); i++ {
file, err := os.Open(flag.Arg(i))
if err != nil {
fmt.Fprintf(os.Stdout, "cat: %s: No such file or directory", flag.Arg(i))
continue
}
cat(bufio.NewReader(file))
}
}