GO基础-I/O操作
大约 4 分钟
文件操作
创建文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Create("example.txt")
if err != nil {
fmt.Println("Error creating file:", err)
return
}
defer file.Close()
fmt.Println("File created successfully.")
}
打开文件
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()
fmt.Println("File opened successfully.")
}
读取文件
按行读取
package main
import (
"fmt"
"bufio"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
fmt.Println(line)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading file:", err)
}
}
场景:
- 读取大文件:避免一次性加载整个文件到内存中。
- 实时处理:读取每行时进行实时处理。
- 逐行处理:适用于对文件内容逐行进行处理的场景,如日志文件分析。
整个读取
package main
import (
"fmt"
"io/ioutil"
)
func main() {
content, err := ioutil.ReadFile("example.txt")
if err != nil {
fmt.Println("Error reading file:", err)
return
}
fmt.Println(string(content))
}
场景:
- 简洁快速:一次性读取整个文件内容,简单且快速。
- 适用于小文件:适合处理小文件,因为将整个文件加载到内存可能会消耗较多资源。
- 整体处理:适用于需要整体处理文件内容的情况,如配置文件读取。
写入文件
无缓冲写入
package main
import (
"fmt"
"os"
)
func main() {
content := []byte("Hello, Go!")
err := ioutil.WriteFile("example.txt", content, 0644)
if err != nil {
fmt.Println("Error writing to file:", err)
return
}
fmt.Println("File written successfully.")
}
有缓冲写入
package main
import(
"os"
"bufio"
"log"
)
func main(){
file,err := os.OpenFile("file.txt",os.O_APPEND,0644)
if err!=nil{
log.Fatal(err)
return
}
defer file.Close()
writer := bufio.NewWriter(file)
_,err = writer.WriteString("这是缓冲写入的")
if err!=nil{
log.Fatal(err)
return
}
writer.Flush()
log.Println("缓冲内容写入成功")
}
func OpenFile(name string, flag int, perm FileMode) (*File, error)
这里的参数解释如下:
name:
"file.txt"
- 文件名,指定了要打开的文件。flag:
os.O_APPEND
- 打开文件的标志。os.O_APPEND
表示在写入数据时,将光标定位到文件末尾,也就是追加模式写入。除此之外,Go 中还提供了其他的标志常量,例如:
os.O_RDONLY
: 只读方式打开文件。os.O_WRONLY
: 只写方式打开文件。os.O_RDWR
: 读写方式打开文件。os.O_CREATE
: 如果文件不存在,则创建文件。os.O_TRUNC
: 如果以写入模式打开文件,并且文件已存在,则将其截断为零长度。可以通过按位或 (
|
) 操作符组合这些标志来达到不同的效果。例如,os.O_RDWR | os.O_CREATE | os.O_APPEND
表示以读写模式打开文件,如果文件不存在则创建,并且以追加模式写入。perm:
0644
- 新建文件的权限模式。这是一个八进制数字,代表了文件的权限。在这个例子中,0644
表示文件所有者有读写权限,而所属组和其他用户只有读权限。在八进制中,权限位的含义如下:
- 第一位表示文件所有者的权限。
- 第二位表示文件所属组的权限。
- 第三位表示其他用户的权限。
权限位的值分别为:
4
表示读权限。2
表示写权限。1
表示执行权限。因此,
0644
转换为二进制就是0110100
,表示文件所有者有读写权限(110
),组和其他用户有读权限(100
)。
使用 bufio 包进行缓冲写入具有以下特点:
- 提高性能:bufio 包提供了缓冲功能,可以减少系统调用次数,从而提高写入操作的性能。通过缓冲写入,可以将多个小写入操作合并为一个更大的写入操作。
- 减少 IO 操作:通过缓冲写入,数据首先被写入到缓冲区中,然后批量写入磁盘(或其他输出源)。这减少了对底层 IO 操作的频繁访问,提高了效率。
- 灵活控制缓冲大小:bufio 提供了对缓冲区大小的灵活控制,可以根据需求调整缓冲区大小以优化性能和内存使用。
- 原子性写入:bufio 提供了原子性写入的功能,即要么写入成功,要么失败,避免了部分数据写入成功而部分失败的情况。
- 支持各种 Writer 接口:bufio.Writer 支持多种 Writer 接口,如文件、网络连接等,使得可以在不同的数据源上实现高效的缓冲写入操作。
- 易用性:bufio 提供了简单且易于使用的 API,使得开发者可以方便地实现缓冲写入操作,而无需处理复杂的底层细节。
文件信息
package main
import (
"fmt"
"os"
)
func main() {
fileInfo, err := os.Stat("example.txt")
if err != nil {
fmt.Println("Error getting file info:", err)
return
}
fmt.Println("File Name:", fileInfo.Name())
fmt.Println("Size (bytes):", fileInfo.Size())
fmt.Println("Permissions:", fileInfo.Mode())
fmt.Println("Is Directory?", fileInfo.IsDir())
}