go语言的嵌入功能 ebmed

我们都知道,go编译的程序非常适合部署

我们一般编译出来的可执行二进制文件都是单个的文件,非常适合复制和部署

还能通过交叉编译在windows上开发编译到linux平台使用

简直不要太爽

但是我们在项目中可能还会用到静态文件,这些是不会编译到二进制程序中去的

例如项目的配置文件

例如项目运行中需要读取的文件

如果这些文件也可以被打包到二进制文件里面,那就太美妙了,编译之后直接一个可执行文件即可搞定

嵌入

  • 对于单个的文件,支持嵌入为字符串和 byte slice
  • 对于多个文件和文件夹,支持嵌入为新的文件系统FS
  • 比如导入 "embed"包,即使无显式的使用
  • go:embed指令用来嵌入,必须紧跟着嵌入后的变量名
  • 只支持嵌入为string, byte slice和embed.FS三种类型,这三种类型的别名(alias)和命名类型(如type S string)都不可以

嵌入字符串

package main

import (
  _ "embed"
  "fmt"
)

//go:embed hello.txt
var data string

func main() {
  fmt.Println(data)
}

嵌入byte slice

package main

import (
  _ "embed"
  "fmt"
)

//go:embed hello.txt
var data []byte

func main() {
  fmt.Println(string(data))
}

嵌入embed.FS

嵌入单个文件

package main

import (
  "embed"
  _ "embed"
  "fmt"
)

//go:embed hello.txt
var fs embed.FS

func main() {
  byteData, err := fs.ReadFile("hello.txt")
  fmt.Println(string(byteData), err)
}


嵌入多个文件

package main

import (
  "embed"
  _ "embed"
  "fmt"
)

//go:embed hello.txt jwt.go
var fs embed.FS

func main() {
  byteData, err := fs.ReadFile("hello.txt")
  fmt.Println(string(byteData), err)
  byteData, err = fs.ReadFile("jwt.go")
  fmt.Println(string(byteData), err)
}

嵌入一个目录

package main

import (
  "embed"
  _ "embed"
  "fmt"
  "path"
)

//go:embed proxy
var fs embed.FS

func main() {
  dir, err := fs.ReadDir("proxy")
  if err != nil {
    fmt.Println(err)
    return
  }
  for _, entry := range dir {
    info, _ := entry.Info()
    fmt.Println(info.Name())
    if info.IsDir() {
      subDir, _ := fs.ReadDir(path.Join("proxy", info.Name()))
      for _, subEntry := range subDir {
        subInfo, _ := subEntry.Info()
        fmt.Printf("  -%s\n", subInfo.Name())
      }
    }
  }
}

注意:go:embed只能用于包级别声明的变量,在函数里面是不能用的

实际应用

有些场合,我们在程序里面会读取一些静态文件,这些静态文件开发好之后就八辈子不会再变了

并且文件也不大

不把它编译到程序里面,到时候部署还得把这个文件移过去移过来,麻烦

例如我的项目,我单独把es的索引写在了json文件里面

func (CdnLogModelEs) Mapping() string {
  byteData, err := os.ReadFile("models/cdn_log_model_mapping.json")
  if err != nil {
    logrus.Error(err)
    panic(err)
    return ""
  return string(byteData)
}

这是之前的写法,只要服务器上要重建索引的适合,必须要把这个json文件给带上去,还是很麻烦的

所以现在的写法就很方便了

//go:embed cdn_log_model_mapping.json
var cdnLogModelMapping string

func (CdnLogModelEs) Mapping() string {
  return cdnLogModelMapping
}

不适合嵌入

  1. 大文件
  2. 经常变化的文件(例如配置文件)

参考文档

embed简明教程 Go embed 简明教程-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值