【GO语言卵细胞级别教程】12.Go 语言文件操作秘籍:高效技巧解锁!

【GO语言卵细胞级别教程】12.Go 语言文件操作秘籍:高效技巧解锁!

🥰微信公众号:【给点知识】分享小知识,快速成长,欢迎关注呀!(底部点击二维码)
🥰本项目演示代码仓库:https://gitee.com/gdzsfun/csdn-study-go 演示项目仓库
🥰本项目创建方式:【GO语言卵细胞级别教程】05.项目创建和函数讲解
🥰学习宗旨:活到老,学到老。
😍写作宗旨:致力于改变现有文章难读难懂问题。
今日分享诗句:
###########
蓬门未识绮罗香,
拟托良媒益自伤。
谁爱风流高格调,
共怜时世俭梳妆。
敢将十指夸针巧,
不把双眉斗画长。
苦恨年年压金线,
为他人作嫁衣裳。

1.文件模块简介

1.1概述

文件操作GO语言提供了os模块和io流

1.2打开文件

Go语言提供了丰富的文件操作功能,下面是一些常见的文件操作:

  1. 打开文件: 使用os.Open函数打开文件,它返回一个*os.File对象和一个可能的错误。可以指定打开文件的模式(只读、只写、追加等)。

    file, err := os.Open("filename.txt")
    if err != nil {
        // 处理错误
    }
    defer file.Close() // 确保在函数结束时关闭文件
    
  2. 创建文件: 使用os.Create函数创建文件,如果文件已存在则截断文件内容。它返回一个*os.File对象和一个可能的错误。

    file, err := os.Create("filename.txt")
    if err != nil {
        // 处理错误
    }
    defer file.Close() // 确保在函数结束时关闭文件
    
  3. 读取文件内容: 使用file.Readfile.ReadAt方法从文件中读取数据。Read方法将数据读取到指定的字节切片中,ReadAt方法从指定的偏移量开始读取数据。它们返回读取的字节数和可能的错误。

    buffer := make([]byte, 1024)
    numBytes, err := file.Read(buffer)
    if err != nil {
        // 处理错误
    }
    
  4. 写入文件内容: 使用file.Writefile.WriteAt方法向文件中写入数据。Write方法从当前位置开始写入数据,WriteAt方法从指定的偏移量开始写入数据。它们返回写入的字节数和可能的错误。

    data := []byte("Hello, World!")
    numBytes, err := file.Write(data)
    if err != nil {
        // 处理错误
    }
    
  5. 重命名文件: 使用os.Rename函数将文件重命名为新的名称。

    err := os.Rename("oldname.txt", "newname.txt")
    if err != nil {
        // 处理错误
    }
    
  6. 删除文件: 使用os.Remove函数删除文件。

    err := os.Remove("filename.txt")
    if err != nil {
        // 处理错误
    }
    
  7. 获取文件信息: 使用os.Stat函数获取文件的详细信息,包括文件名、大小、修改时间等。

    fileInfo, err := os.Stat("filename.txt")
    if err != nil {
        // 处理错误
    }
    fmt.Println("文件名:", fileInfo.Name())
    fmt.Println("文件大小:", fileInfo.Size())
    fmt.Println("修改时间:", fileInfo.ModTime())
    

这只是一些常见的文件操作示例,Go语言的osio包提供了更多功能丰富的文件操作函数。

1.3实战案例

  1. 获取文件基本信息和内容,具体步骤入下:
    1. 首先使用os.Open打开文件获取句柄
    2. 使用句柄获取文件的基本信息,名称、路径等
    3. 使用句柄获取文件的属性信息:调用Stat()方法获取属性结构体
    4. 使用属性结构体获取文件的具体属性:大小、权限等
    package mystudy
    
    import (
    	"fmt"
    	"os"
    	"path" // path只能处理一种路径\\
    	"path/filepath" // filepath 可以处理相对复杂的分隔符 提供了相对路径和绝对路径的处理方法
    )
    
    func DemoFile01() {
    	fmt.Println("------文件操作------")
    	file, err := os.Open("D:/07.go/02.gostudy/goproject/src/com/gdzs/main/main.go")
    	if err != nil {
    		fmt.Println("Error:", err)
    		return
    	}
    	defer file.Close()
    	fmt.Println("文件绝对路径:", file.Name())
    	fmt.Println("文件名:", path.Base("D:/07.go/02.gostudy/goproject/src/com/gdzs/main/main"))
    	fmt.Println("文件名称:", filepath.Base("D:\\07.go\\02.gostudy\\goproject\\src\\com\\gdzs\\main\\main.go"))
        fmt.Println(os.UserHomeDir())
    	fileInfo, err := file.Stat()
    	if err != nil {
    		fmt.Println("Error:", err)
    		return
    	}
    
    	fmt.Println("文件模式和权限:", fileInfo.Mode())
    	fmt.Println("文件大小:", fileInfo.Size())
    	fmt.Println("------读取文件的内容------")
    	data := make([]byte, 1000)
    	for{
    		if numBytes, err := file.Read(data);numBytes > 0{
    			fmt.Printf("%q, %v, %v", data[:numBytes], err, numBytes)
    		}else{
    			fmt.Println("output ok:")
    			break
    		}
    	}
    
    }
    // 输出结果
    ------文件操作------
    文件绝对路径: D:/07.go/02.gostudy/goproject/src/com/gdzs/main/main.go
    文件名: main
    文件名称: main.go
    C:\Users\12862 <nil>
    文件模式和权限: -rw-rw-rw-
    文件大小: 2724
    ------读取文件的内容------
    "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"com.gdzs/goproject/src/com/gdzs/mystudy\"\r\n\t_\"github.com/gin-gonic/gin\"\r\n)\r\n\r\nfunc init(){\r\n\tfmt.Println(\"init函数执 行了\")\r\n}\r\n//“
    
    
  2. 文件的打开、创建、读取、写入、重命名、获取信息等操作
    1. 打开文件:os.Open
    2. 创建文件:os.Create
    3. 读取文件:句柄.Read(buffer)
    4. 写入文件:句柄.Write(data)
    package mystudy
    
    import (
    	"fmt"
    	"os"
    	_"path" // path只能处理一种路径\\
    	_"path/filepath" // filepath 可以处理相对复杂的分隔符 提供了相对路径和绝对路径的处理方法
    )
    //打开文件函数
    func OpenFile(filePath string) *os.File {
    	fmt.Println("------打开文件------")
    	var filePhth string = filePath
    	// 打开文件:如果要以何种模式打开可以使用
    	// file, err := os.OpenFile("data.txt", os.O_RDONLY, 0644)
    	// os.O_RDONLY参数表示只读模式,0644是文件权限。如果文件打开成功,
    	// 将输出"File opened successfully.",否则输出错误信息。
    	file, err := os.Open(filePhth)
    	if err !=nil{
    		panic(err)
    		return nil
    	}
    	return file
    }
    // 创建文件
    func CreateFile(fileName string) *os.File {
    	fmt.Println("------创建文件------")
    	file, err :=os.Create(fileName)
    	if err != nil {
    		panic(fmt.Sprintf("创建文件失败: %s", err))
    	}
    	return file
    }
    // 读取文件
    func ReadFile(file os.File){
    	// 将指针移动到头部
    	_, err := file.Seek(0, 0)
    	buffer := make([]byte, 13)
    	numBytes, err := file.Read(buffer)
    	fmt.Println("读取文件大小:", numBytes, err)
    	fmt.Printf("文件内容:%q\n", buffer[:])
    }
    // 写入文件内容
    func WriteFile(file *os.File){
    	fmt.Println("---写入文件内容---")
    	data := []byte("hello, World!")
    	numBytes, _ := file.Write(data) 
    	fmt.Println(numBytes)
    }
    // 重命名文件
    func RenameFile(oldName string, fileName string){
        err := os.Rename(oldName, fileName)
    	fmt.Println("err:",  err)
    }
    // 获取文件信息
    func GetFileInfo(fileName string){
    	fileInfo, _ := os.Stat(fileName)
    	fmt.Println("文件名:", fileInfo.Name())
    	fmt.Println("文件大小", fileInfo.Size())
    	fmt.Println("修改时间", fileInfo.ModTime())
    }
    
    func DemoFile01() {
    	fmt.Println("------文件操作------")
    	defer func(){
    		if r:= recover();r != nil{
    			fmt.Println("Panic:", r)
    			return 
    		}
    	}()
    	var filePath string = "D:\\07.go\\02.gostudy\\goproject\\src\\com\\gdzs\\main\\main.go"
    	// 获取文件信息
    	GetFileInfo(filePath)
    	file := OpenFile(filePath)
    	if file != nil{
    		fmt.Println(file)
    	}else{
    		fmt.Println("打开文件失败")
    	}
    	// 创建文件
    	createFile := CreateFile("gdzs.go")
    	fmt.Println(createFile)
    	// 写入数据
    	WriteFile(createFile)
    	// 读取文件
    	ReadFile(*createFile)
    	createFile.Close()
    	RenameFile("gdzs.go", "gdzs.txt")
    
    }
    // 输出结果
    ------文件操作------
    文件名: main.go
    文件大小 2724
    修改时间 2024-04-15 15:27:30.7824836 +0800 CST
    ------打开文件------
    &{0xc0003ff180}
    ------创建文件------
    &{0xc0003ff400}
    ---写入文件内容---
    13
    读取文件大小: 13 <nil>
    文件内容:"hello, World!"
    err: <nil>
    

2.io流操作文件

文本作者公众号:
在这里插入图片描述

2.1io流简介

io流一般用于处理文件不是很大的。
有了os模块可以操作文件,那么为什么还需要io流呢?
IO 流适用于许多不同的场景,特别是在处理数据流、文件和网络传输时。以下是一些适合使用 IO 流的常见场景:

  1. 文件读写:IO 流提供了读取和写入文件数据的高级接口,可以逐块地读取或写入文件内容。这对于处理大型文件或需要逐行读取文本文件等情况非常有用。
  2. 网络传输:在网络编程中,IO 流用于读取和写入网络套接字数据。通过使用 net.Conn 类型的 IO 流,您可以从网络连接中读取数据,或将数据写入到网络连接中,实现与远程服务器的通信。
  3. 数据流处理:IO 流适用于处理连续的数据流,而不是一次性加载所有数据。这在处理大量数据或需要实时处理数据的情况下非常有用。通过逐块地读取和处理数据流,可以降低内存消耗,并提高处理效率。
  4. 数据转换处理:IO 流提供了灵活的接口和方法,可以对数据进行转换和处理。通过组合多个 IO 流、使用缓冲区、使用编码解码器等,可以实现各种数据转换和处理操作,如压缩、加密、解析等。
  5. 多路复用:IO 流支持多路复用,可以同时处理多个数据源或数据目标。通过使用并发或异步的方式,可以同时处理多个 IO 流,从而提高系统的并发性和效率。

os.File 类型实现了 io.Readerio.Writerio.Closer 等接口,这使得 os.File 可以通过 Read()Write() 等方法进行数据的读取和写入。这样,我们可以使用 os 包打开文件,然后使用 io 包提供的通用接口和函数来处理文件数据。
在这里插入图片描述

2.2IO流操作文件实战

  1. io的两种读取方式:使用io/ioutil模块 ioutil.ReadFile(filePath):这个方法已经内置了关闭和打开文件,所以这里不需要关注文件打开关闭,可以直接调用读取方法读取
  2. 另外一只是一行行 读使用io需要写文件的读写与关闭
    file2,  _ := os.Open(filePath)
    defer file2.Close()
    // 创建一个流
    reader := bufio.NewReader(file2)
    for{
    	str, err := reader.ReadString('\n')
    	if err == nil || err == io.EOF{
    		fmt.Println(str)
    	}
    	if err == io.EOF {
    		fmt.Println("---读完了---")
    		break
    	} else if err != nil {
    		fmt.Println("Failed to read file:", err)
    		break
    	}
    }
    
  3. 代码实践
    package mystudy
    // io流读取文件
    import (
    	"fmt"
    	"io/ioutil"
    	"os"
    	"bufio"
    	"io"
    )
    
    func DemoIoFile(){
    	var filePath string = "D:/07.go/02.gostudy/gdzs.txt"
    	defer func(){
    		if err := recover();err != nil{
    			fmt.Println("报异常:", err)
    			return 
    		}
    	}()
    	//io读取文件:自带了文件的开关
    	file, err := ioutil.ReadFile(filePath)
    	if err != nil {
    		fmt.Println("读取出错,错误为:", err)
    	}
    	fmt.Printf("%v\n",string(file))
    	//带有缓存的读取方式
    	fmt.Println("---带有缓存的读取方式---")
    	file2,  _ := os.Open(filePath)
    	fmt.Println(file2)
    	defer file2.Close()
    	// 创建一个流
    	reader := bufio.NewReader(file2)
    	for{
    		str, err := reader.ReadString('\n')
    		if err == nil || err == io.EOF{
    			fmt.Println(str)
    		}
    		if err == io.EOF {
    			fmt.Println("---读完了---")
    			break
    		} else if err != nil {
    			fmt.Println("Failed to read file:", err)
    			break
    		}
    	}
    	
    
    }
    

2.3其他的用途:

  1. 标准输入读取:

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    func main() {
    	scanner := bufio.NewScanner(os.Stdin)
    
    	for scanner.Scan() {
    		line := scanner.Text()
    		fmt.Println("Input:", line)
    	}
    
    	if err := scanner.Err(); err != nil {
    		fmt.Println("Error:", err)
    	}
    }
    
  2. 标准输出写入:

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    )
    
    func main() {
    	writer := bufio.NewWriter(os.Stdout)
    	message := "Hello, World!"
    
    	_, err := writer.WriteString(message)
    	if err != nil {
    		fmt.Println("Error:", err)
    	}
    
    	err = writer.Flush()
    	if err != nil {
    		fmt.Println("Error:", err)
    	}
    }
    
  3. 网络通信中的缓冲读取:

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"net"
    )
    
    func main() {
    	conn, err := net.Dial("tcp", "example.com:80")
    	if err != nil {
    		fmt.Println("Error:", err)
    		return
    	}
    	defer conn.Close()
    
    	reader := bufio.NewReader(conn)
    
    	for {
    		line, err := reader.ReadString('\n')
    		if err != nil {
    			fmt.Println("Error:", err)
    			break
    		}
    		fmt.Println("Received:", line)
    	}
    }
    
  4. 字符串缓冲读写:

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"strings"
    )
    
    func main() {
    	input := "Hello\nWorld\n"
    	reader := bufio.NewReader(strings.NewReader(input))
    
    	for {
    		line, err := reader.ReadString('\n')
    		if err != nil {
    			break
    		}
    		fmt.Println("Line:", line)
    	}
    
    	writer := bufio.NewWriter(strings.NewWriter())
    	message := "Hello, World!"
    	_, err := writer.WriteString(message)
    	if err != nil {
    		fmt.Println("Error:", err)
    	}
    
    	err = writer.Flush()
    	if err != nil {
    		fmt.Println("Error:", err)
    	}
    
    	output := writer.String()
    	fmt.Println("Output:", output)
    }
    

3.文件写入综合实践

  1. 需要os.OpenFile()打开文件
  2. 使用bufio写入内容
    package mystudy
    // 文件写入
    import "fmt"
    import "os"
    import "bufio"
    
    func DemoWriteFile(){
    	var filePath = "D:/07.go/02.gostudy/gdzs.txt"
    	file, _:= os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os.O_CREATE, 0666)
    	writer := bufio.NewWriter(file)
    	for i:=0; i<=6; i++{
    		writer.WriteString("你好,中国")
    	}
    	writer.Flush()
    	fmt.Println(file)
    	defer file.Close()
    }
    
  3. 参数详解
    在 Go 语言中,os.OpenFile() 函数的第二个参数是一个标志位,用于指定文件的打开模式和权限。在您提到的例子中,0666 是一个表示文件打开模式和权限的八进制数。
    在八进制数 0666 中,每个数字代表一组权限,共有四组权限:所有者权限、所有者所属组权限、其他人权限以及特殊权限。每组权限由三个二进制位表示,分别代表读、写和执行权限。
    具体解释如下:
    • 第一组(最高位)代表所有者权限。0 表示没有权限,6 表示所有者具有读和写权限。
    • 第二组代表所有者所属组权限。6 表示所有者所属组具有读和写权限。
    • 第三组代表其他人权限。6 表示其他人具有读和写权限。
    • 第四组(最低位)代表特殊权限,例如粘着位、SGID 位、SUID 位等。在这种情况下,0 表示没有特殊权限。
      0666 转换为二进制表示为 110 110 110,意味着所有者、所有者所属组和其他人都具有读和写权限。
      因此,os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666) 使用 0666 打开模式表示创建文件(如果文件不存在)并为该文件设置读和写权限,使得所有者、所有者所属组和其他人都可以读取和写入该文件。
      需要注意的是,使用 0666 权限设置可能会导致较为宽松的权限,具体权限设置应根据实际需求和安全性考虑进行选择。
  4. st权限
    在文件权限中,“st” 表示文件的 Set UID (SUID) 和 Set GID (SGID) 权限。
    • Set UID (SUID):当一个可执行文件被设置了 SUID 权限时,无论谁执行该文件,都会暂时以该文件的所有者身份来执行。这意味着执行者将具有该文件所有者的权限和特权。SUID 权限对于某些需要特定权限才能执行的程序非常有用,例如密码更改程序 passwd
    • Set GID (SGID):当一个可执行文件被设置了 SGID 权限时,无论谁执行该文件,都会以该文件所属组的身份来执行。与 SUID 类似,SGID 也允许执行者暂时获得执行文件所属组的权限和特权。
      这些权限标志通常在文件的权限位中表示为 “s” 或 “S”,具体取决于执行者是否同时具有执行权限。
    • 小写 “s” 表示设置了 SUID 或 SGID 权限,并且对应的执行权限也被设置。
    • 大写 “S” 表示设置了 SUID 或 SGID 权限,但对应的执行权限未被设置。
      以下是一些示例:
    • -rwsr-xr-x:具有 SUID 权限的可执行文件,所有者具有读、写和执行权限,组和其他人具有执行权限。
    • -rwxr-sr-x:具有 SGID 权限的可执行文件,所有者具有读、写和执行权限,组具有读、执行权限,其他人具有执行权限。
      设置 SUID 和 SGID 权限需要谨慎,以确保文件的安全性和权限控制。

4.文件复制

复制的原理就是,从一个文件中读取数据,然后写入新的文件中,这里使用ioutil包实现

package mystudy
// 文件复制
import (
	f"fmt"
	"io/ioutil"
)

func DemoFileCopy(){
	f.Println("---文件复制---")
	filePath1 := "gdzs.txt"
	filePath2 := "demo02.txt"
	// 读取文件
	content, err:= ioutil.ReadFile(filePath1)
	f.Println(content)
	// 写入文件
	err = ioutil.WriteFile(filePath2, content, 0666)
	if err != nil{
		f.Println("复制文件-写入错误", err)
	}

}

5.os包和bufio包操作文件的区别

5.1概述

os包和bufio包是Go语言标准库中用于文件操作的两个不同的包,它们有一些区别和不同的用途。
os 包:
os包提供了与操作系统交互的功能,包括文件和目录的创建、打开、读取、写入、删除等操作。它提供了底层的文件操作接口,可以直接操作文件描述符。os包中的函数返回的错误类型是error,需要显式地进行错误处理。它适用于对文件进行较底层、原始的读写操作。
bufio 包:
bufio包提供了带缓冲功能的 I/O 操作,可以提高文件读写的效率。它基于io.Readerio.Writer接口,提供了带缓冲的读取(bufio.Reader)和写入(bufio.Writer)操作。bufio包内部维护了一个缓冲区,可以减少对底层文件的实际读写次数。它还提供了一些便利的函数,如按行读取文本文件等。bufio包中的函数返回的错误类型是error,需要显式地进行错误处理。它适用于高效的文件读写操作。

5.2代码演示

示例代码:
使用 os 包进行文件读写:

package main

import (
	"fmt"
	"log"
	"os"
)

func main() {
	file, err := os.OpenFile("filename.txt", os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	data := []byte("Hello, World!")
	_, err = file.Write(data)
	if err != nil {
		log.Fatal(err)
	}

	readData := make([]byte, 1024)
	_, err = file.Read(readData)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("读取的数据:%s\n", readData)
}

使用 bufio 包进行文件读写:

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
	file, err := os.OpenFile("filename.txt", os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	writer := bufio.NewWriter(file)
	data := []byte("Hello, World!")
	_, err = writer.Write(data)
	if err != nil {
		log.Fatal(err)
	}
	writer.Flush()

	reader := bufio.NewReader(file)
	readData, err := reader.ReadString('\n')
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("读取的数据:%s\n", readData)
}

注意,在以上的示例代码中,我们使用了不同的读取方式,os包直接调用了file.Read方法读取数据,而bufio包通过bufio.NewReader创建了一个带缓冲的读取器,并使用reader.ReadString按行读取数据。
简而言之,os包适用于较底层的文件读写操作,而bufio包提供了更高级、带缓冲的文件读写功能。选择使用哪个包取决于您的具体需求和场景。

5.3特点和用法

当涉及到文件操作时,os包和bufio包在功能和用途上有一些区别,下面将进一步详细介绍它们的特点和用法。
os 包的特点和用法:

  • os包提供了一组函数,用于创建、打开、读取、写入、删除和操作文件和目录。
  • 它提供了底层的文件操作接口,可以直接操作文件描述符。
  • os包中的函数返回的错误类型是error,需要显式地进行错误处理。
  • os包提供的函数可以用于读取和写入任意类型的数据,但需要手动处理数据的格式和解析。
  • 适用于对文件进行较底层、原始的读写操作。
  • 提供了文件的权限设置、文件信息获取等功能。
    bufio 包的特点和用法:
  • bufio包提供了带缓冲功能的 I/O 操作,可以提高文件读写的效率。
  • 它基于io.Readerio.Writer接口,提供了带缓冲的读取和写入操作。
  • bufio包内部维护了一个缓冲区,可以减少对底层文件的实际读写次数,提高性能。
  • bufio包提供了一些便利的函数,如按行读取文本文件、读取指定字节数的数据等。
  • bufio包中的函数返回的错误类型是error,需要显式地进行错误处理。
  • 适用于高效的文件读写操作,特别是处理大量数据时。

使用 os 包读取文件的所有行:

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
)

func main() {
	file, err := os.Open("filename.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		fmt.Println(line)
	}

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
}

使用 bufio 包写入文件的所有行:

package main

import (
	"bufio"
	"log"
	"os"
)

func main() {
	file, err := os.OpenFile("filename.txt", os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	writer := bufio.NewWriter(file)
	lines := []string{"Line 1", "Line 2", "Line 3"}

	for _, line := range lines {
		_, err := writer.WriteString(line + "\n")
		if err != nil {
			log.Fatal(err)
		}
	}

	writer.Flush()
}

5.4问题

  1. 100G的文件,内存只有8G 使用那种方式读取呢?
    那么最好的选择是使用逐行读取的方式,以避免将整个文件加载到内存中。可以使用bufio.Scanner来按行读取文件。bufio.Scanner会逐行地读取文件内容,而不会一次性将整个文件加载到内存中。这种方法可以在有限的内存下有效地处理大型文件。
    示例代码:
    package main
    
    import (
    	"bufio"
    	"fmt"
    	"log"
    	"os"
    )
    
    func main() {
    	file, err := os.Open("largefile.txt")
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer file.Close()
    
    	scanner := bufio.NewScanner(file)
    
    	for scanner.Scan() {
    		line := scanner.Text()
    		// 在这里处理每一行的数据
    		fmt.Println(line)
    	}
    
    	if err := scanner.Err(); err != nil {
    		log.Fatal(err)
    	}
    }
    

通过逐行读取文件,可以在有限的内存下处理大型文件,并逐行对文件内容进行处理,而不会超出内存限制。
在这里插入图片描述

  • 35
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值