读取文件

读取文件是一个经常用到的功能,比如从文件目录中读取一张照片,读取一个txt文件,word,excel等等,今天我们就学习一下go是如何读取文件的?

本节你将学到的内容如下

  • 使用绝对文件路径
  • 使用命令行标记来传递文件路径
  • 将文件绑定在二进制文件中
  • 分块读取文件
  • 逐行读取文件

使用绝对文件路径

我们现在项目中创建一个文件 log.txt

1594482-e460e72a54780bdb
image.png
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    data, err := ioutil.ReadFile("log.txt")
    if err != nil {
        fmt.Println("读取失败了", err)
        return
    }
    fmt.Println("读取内容:", string(data))
}
1594482-bec8db8f0e7f0317
image.png

我看发现这个文件找不到,为什么?

go 是编译类型的语言,编译后的程序目录和log已经不再同一个目录下面,所以代码在当前目录是找不到文件的

那么怎么才能访问到这个文件呢?

使用绝对路径,代码如下

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    data, err := ioutil.ReadFile("/Users/xujie/go/src/awesomeProject/main/log.txt")
    if err != nil {
        fmt.Println("读取失败了", err)
        return
    }
    fmt.Println("读取内容:", string(data))
}
1594482-7f250f8dbbe416eb
image.png

我们已经读取到log.txt 文件里的内容了


使用命令行标记来传递文件路径

flag 包,我们可以从输入的命令行获取到文件路径,接着读取文件内容。

首先我们来看看 flag 包是如何工作的。flag 包有一个名为 String 的函数。该函数接收三个参数。第一个参数是标记名,第二个是默认值,第三个是标记的简短描述。

下面看代码如何实现

package main
import (
    "fmt"
    "io/ioutil"
     "flag"
)
func main() {
    fptr := flag.String("fpath","log.txt","这个是读取文件的命令")
    flag.Parse()
    fmt.Println(*fptr)
    data, err := ioutil.ReadFile(*fptr)
    if err != nil {
        fmt.Println("读取失败了", err)
        return
    }
    fmt.Println("读取内容:", string(data))
}
1594482-1e1972d7a06ce25e
image.png

这种方法是使用命令传参的方式执行文件

将文件绑定在二进制文件中

先安装一个第三方包

go get -u github.com/gobuffalo/packr
package main

import (
    "fmt"
    "github.com/gobuffalo/packr"
)

func main() {
    box := packr.NewBox("") // 相对当前go文件的目录
    data := box.String("log.txt")
    fmt.Println("读取内容:", data)
}
1594482-8b7732b129ab42d0
image.png

三种读取文件的方式已经讲完了,但是有没有发现,我们通过上面的方式读取的都是整个文件,那么怎么分块读取文件呢?


分块读取文件
package main
import (
    "os"
    "bufio"
    "fmt"
)

func main() {
   f ,err:= os.Open("/Users/xujie/go/src/awesomeProject/main/log.txt")
    defer func() {
        if err = f.Close(); err != nil {
            fmt.Print(err)
        }
    }()
   if(err != nil){
       fmt.Print(err)
       return
   }
    // 1.创建一个读文件
    r := bufio.NewReader(f)
    // 2.创建三个字节的缓冲区 一个汉字对应三个字节
    b := make([]byte,3)
    for {
        // 3.按三个字节读取文件
        n,err := r.Read(b)
        if err != nil {
            break;
        }
        fmt.Println(n)
        fmt.Println(string(b))
    }
}
1594482-f195770f43debc92
image.png

读取文件的步骤

1 .打开文件
2.创建读取文件结构体
3.创建读取缓冲区
4.读取文件
5.关闭文件


逐行读取文件

package main

import (
"os"
"bufio"
"fmt"
"qiniupkg.com/x/log.v7"
)

func main() {
f ,err:= os.Open("/Users/xujie/go/src/awesomeProject/main/log.txt")
defer func() {
if err = f.Close(); err != nil {
fmt.Print(err)
}
}()

if(err != nil){
fmt.Print(err)
return
}
// 1.创建一个读文件
s := bufio.NewScanner(f)

i:=0

// 2.
for s.Scan() {

   fmt.Println(i)
   fmt.Println(s.Text())
   i++
}
err = s.Err()
if err != nil {
    log.Fatal(err)
}

}

1594482-f0f9d1e4eb56e0c6
image.png

解释一下

bufio.NewScanner() 返回的是如下的对象

type Scanner struct {
    r            io.Reader // The reader provided by the client.
    split        SplitFunc // The function to split the tokens.
    maxTokenSize int       // Maximum size of a token; modified by tests.
    token        []byte    // Last token returned by split.
    buf          []byte    // Buffer used as argument to split.
    start        int       // First non-processed byte in buf.
    end          int       // End of data in buf.
    err          error     // Sticky error.
    empties      int       // Count of successive empty tokens.
    scanCalled   bool      // Scan has been called; buffer is in use.
    done         bool      // Scan has finished.
}

Scan() 方法读取文件的下一行,如果可以读取,就可以使用 Text() 方法,指导读取到文件的最后一行,此时如果文件中已经是最好一行了,你任然调用Scan 你就会得到一个false值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值