golang读取文件总结

1. 读取整个文件

读取整个文件是效率最高的一种方式,但其只适用于小文件,大文件一次读取会消耗大量内存

 

1.1 使用文件名直接读取

使用os.ReadFile()方法可以实现直接读取

func fileOne() {
content, err := os.ReadFile("test.txt")
if err != nil {
panic(err)
}
fmt.Println(string(content))
}

 

使用ioutil.ReadFile()方法可以实现一样的效果,这两个函数其实是完全一样的

func fileTwo() {
content, err := ioutil.ReadFile("test.txt")
if err != nil {
panic(err)
}
fmt.Println(string(content))
}

 

1.2 先创建文件句柄再读取文件

如果想以只读方式打开文件的话,可以直接使用os.Open()方法

func fileThree() {
file, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer file.Close()
content, err := ioutil.ReadAll(file)
fmt.Println(string(content))
}

 

或者使用通用的os.OpenFile()方法,不过要多加两个参数

func fileFour() {
file, err := os.OpenFile("test.txt", os.O_RDONLY, 0)
if err != nil {
panic(err)
}
defer file.Close()
content, err := ioutil.ReadAll(file)
fmt.Println(string(content))
}

 

2. 按行读取

按行读取主要使用ioutil库,其中有两个方法可以实现按行读取

但要注意的是,按行读取是以'\n'来区分每一行的,如果是没有分行的大文件,就不能使用按行读取了

 

使用ioutil.ReadBytes()实现按行读取文件

func fileFive() {
// 创建文件句柄
fi, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer fi.Close()
// 创建reader
r := bufio.NewReader(fi)
for {
lineBytes, err := r.ReadBytes('\n')
line := strings.TrimSpace(string(lineBytes))
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF {
break
}
fmt.Println(line)
}
}

 

使用ioutil.ReadString()同样可以实现按行读取

func fileSix() {
// 创建文件句柄
fi, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer fi.Close()
// 创建reader
r := bufio.NewReader(fi)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF {
break
}
fmt.Println(line)
}
}

 

3. 按字节数读取

对于不分行的大文件来说,只能使用按字节读取来读取整个文件

按字节读取可以使用os库或者syscall库来实现

 

使用os库实现按字节读取

func fileSeven() {
// 创建文件句柄
fi, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer fi.Close()
// 创建reader
r := bufio.NewReader(fi)
// 每次读取1024个字节
buf := make([]byte, 1024)
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
}
}

 

使用syscall库实现按字节读取

func fileEight() {
fd, err := syscall.Open("test.txt", syscall.O_RDONLY, 0)
if err != nil {
fmt.Println("Failed on open: ", err)
}
defer syscall.Close(fd)
var wg sync.WaitGroup
wg.Add(2)
dataChan := make(chan []byte)
go func() {
wg.Done()
for {
data := make([]byte, 100)
n, _ := syscall.Read(fd, data)
if n == 0 {
break
}
dataChan <- data
}
close(dataChan)
}()
go func() {
defer wg.Done()
for {
select {
case data, ok := <-dataChan:
if !ok {
return
}
fmt.Println(string(data))
default:
}
}
}()
wg.Wait()
}

 

posted @   aganippe  阅读(788)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示