Go学习——9.文件读取

文件读取

1. 学习内容

  • 把整个文件读进内存
    • 使用文件的绝对路径
    • 文件路径作为命令行参数传递
    • 将文件绑定到二进制文件中
  • 一小块一小块地读取文件
  • 一行一行地读取文件

2.把整个文件读进内存

最基本的文件操作就是把整个文件读进内存中。

  • 使用ioutil包下的ReadFile函数即可完成
package main

import (
	"fmt"
	"io/ioutil"
)

func main() {
	data, err := ioutil.ReadFile("./test.txt")
	if err != nil {
		fmt.Println("File reading error: ", err)
		return
	}
	fmt.Println(data) // 读取到文件内容的字符串ASC码构成的切片[97 115 100 115 97 100 97 115 100 97 115 100]
	fmt.Println(string(data)) // 将字符串切片转成字符串
}
  • 因为 Go 是编译型语言。go install 会根据源代码创建一个二进制文件。二进制文件独立于源代码,可以在任何位置上运行。由于在运行二进制文件的位置上没有找到 test.txt,因此程序会报错,提示无法找到指定的文件。这是相对于二进制文件的路径。
    • 有三种方法可以解决这个问题
      • 使用绝对文件路径
      • 将文件路径作为命令行标志传递
      • 将文件绑定在二进制文件中
2.1 使用绝对文件路径

绝对路径的话,可以在文件任何位置运行

package main

import (
	"fmt"
	"io/ioutil"
)

func main() {
	data, err := ioutil.ReadFile("E:/奋战2021/1.go语言体系/1.Google资深工程师深度讲解Go语言/code/test.txt")
	if err != nil {
		fmt.Println("File reading error: ", err)
		return
	}
	fmt.Println(data) // 读取到文件内容的字符串ASC码构成的切片[97 115 100 115 97 100 97 115 100 97 115 100]
	fmt.Println(string(data)) // 将字符串切片转成字符串
}
2.2 将文件路径作为命令行标志传递
  • 要借助以下几样东西:
    • flag包
    • flag包具有的一个String函数,即flag.String(标记的名称,标记的默认值,标记的剪短描述)
      • 返回值就是
    • flag.Parse()
      • 在程度访问flag之前,都必须调用flag.Parse()
  • 举例:
import (
	"fmt"
	"flag"
)

func main() {
	fptr := flag.String("fpath", "test.txt", "descval") // 代表将"test.txt"给这个标志"flag",返回标志的值对应的地址,默认即存储"test.txt"的地址
	flag.Parse()
	fmt.Println(*fptr) // 取地址对应的值"test.txt"
}
  • 然后go build产生exe文件
  • 然后使用如下命令,就会将/文件夹路径/test.txt赋值给fpath(fpath默认值是"test.txt"),/文件夹路径/是当前文件夹绝对路径

./exe文件 -fpath=/文件夹路径/test.txt

  • 所以如果上面这段代码,执行了上面的命令,则打印的*fptr不再是默认值,而是文件test.txt的绝对路径

  • 完整命令行读取文件的代码及命令

import (
	"fmt"
  "flag"
  "io/ioutil"
)

func main() {
	fptr := flag.String("fpath", "test.txt", "descval") // 代表将"test.txt"给这个标志"flag",返回标志的值对应的地址,默认即存储"test.txt"的地址
	flag.Parse()
  data, err := ioutil.ReadFile(*fptr)
  if err != nil {
    fmt.Println("Read file error: ", err)
    return
  }
  fmt.Println(string(data)) // 返回文件内容
}

执行命令: ./code.exe -fpath=/e/奋战2021/1.go语言体系/1.Google资深工程师深度讲解Go语言/code/test.txt

2.3 将文件绑定在二进制文件中-----这块还不是很懂!!!!!!!!!!!!!
  • 步骤:
    1. 安装paker包

    go get -u github.com/gobuffalo/packr (具体地址再百度下)

    1. 写执行程序
    package main
    
    import (
        "fmt"
    
        "github.com/gobuffalo/packr" // 引入packr包
    )
    
    func main() {
        box := packr.NewBox("../code") // 创建一个box,这个box代表一个文件夹,文件夹中的内容会被嵌入到二进制文件中
        data := box.String("test.txt") // 读取box中test.txt文件的内容
        fmt.Println("Contents of file:", data)
    }
    
    
    1. 创建二进制文件

    go build

    • 会产生code.exe
    1. 执行code.exe

    ./code.exe

    • 即会执行上面的代码,打印出文件内容

3.一小块一小块的读取文件

当文件内容很大时,不能一次性读取到内存中,这时候可以考虑一小块一小块读取

  • 举例:以3字节的块一块一块读取文件test.txt
package main

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

func main()  {
	// 首先用命令行中接收文件路径,文件路径就是*filePoint
	filePoint := flag.String("filePath", "test.txt", "readFile")
	flag.Parse()

	f, err := os.Open(*filePoint) // 打开文件
	if err != nil { // 错误处理
		log.Fatal(err)
	}
	defer func(){ // 延迟处理,延迟文件的关闭,这样读完就会关闭
		if err = f.Close(); err !=nil {
			log.Fatal(err)
		}
	}()

	// 创建一个缓冲区reader
	r := bufio.NewReader(f)
	b := make([]byte, 3) // 创建一个3字节的切片,每次读取都存在这个切片中
	for {
		n, err := r.Read(b) // 按照切片的长度去读取(读之前清空b),也就是每次读3个字节,并存到b中,返回读取的长度
		if err != nil { // 错误处理,一旦读完,就是返回一个EOF错误
			fmt.Println("Error reading file: ", err)
			break
		}
		fmt.Println(string(b[0:n])) // 打印出每次读取的内容转成字符串,注意中文可能会有问题,三个字符可能会出现不是完整的汉字
	}
}

4.一行一行的读取文件

package main

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

func main()  {
	// 首先用命令行中接收文件路径,文件路径就是*filePoint,是相对路径
	filePoint := flag.String("filePath", "test.txt", "readFile")
	flag.Parse()

	f, err := os.Open(*filePoint) // 打开文件
	if err != nil { // 错误处理
		log.Fatal(err)
	}
	defer func(){ // 延迟处理,延迟文件的关闭,这样读完就会关闭
		if err = f.Close(); err !=nil {
			log.Fatal(err)
		}
	}()

	// 创建一个scabber
	s := bufio.NewScanner(f)
	for s.Scan() { // 扫描每一行,如果存在,则打印
		fmt.Println(s.Text()) // 转成字符串
	}
	err = s.Err() // 监听错误
	if err != nil {
		log.Fatal(err)
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值