读取文件

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

本节你将学到的内容如下

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

使用绝对文件路径

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

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))
}
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))
}
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))
}
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)
}
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))
    }
}
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)
}

}

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值

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 当我们快乐的使用js写服务端程序的时候,是否想过如此酸爽的编程体验是如何实现的。为了满足自己的好奇心,我特意下载了...
    转角遇见一直熊阅读 1,221评论 0 0
  • 简单介绍 关于数据驱动的形式有很多,我们既可以通过定义变量的方式进行参数化,也可以通过定义数组、字典方式进行参数化...
    M_派森阅读 804评论 0 1
  • 我走到车站 长长的龙排到对面 还拐了几个弯 我买份小吃 也得排着队等上半天 我想逛逛商场 人多得肩挨着肩 人真多 ...
    云里风铮阅读 480评论 7 14
  • Je ne suis pas une fille qui connais bien l'art de langue...
    Soussol阅读 203评论 4 0
  • title: js面向对象date: 2017年8月17日 18:58:05updated: 2017年8月27日...
    lu900618阅读 581评论 0 2