便携式的Go模块,其中包含必须读取的捆绑文件。

huangapple go评论80阅读模式
英文:

Portable Go module with bundled files that must be read

问题

我正在尝试创建一个可移植的Go模块,将在许多不同的项目中重复使用。为了使该模块正常工作,它需要能够读取作为模块一部分捆绑的非Go文件。在这种情况下,它们是一些证书捆绑包。选择要加载的文件是动态的,并基于输入参数。

在加载这些文件时,最好的方法是如何指定路径?我似乎找不到任何Go函数来获取相对于模块的路径(而不是相对于使用此模块的可执行文件的路径)。例如,如果我的模块结构如下所示:

mymodule/
  go.mod
  go.sum
  loadcerts.go
  certs/
    cert_A.pem
    cert_B.pem

我需要做类似这样的操作:

// loadcerts.go

package mymodule

func LoadCerts(useB bool) error {
	newCertPool := x509.NewCertPool()

    // 这只是为了显示选择是动态的,由于有许多不同的潜在文件要加载,我们无法将它们全部嵌入
    bundleName := "cert_A.pem"
    if useB {
        bundleName = "cert_B.pem"
    }
	pem, err := ioutil.ReadFile(fmt.Sprintf("./certs/%s", bundleName))
	if err != nil {
		return err
	}
	if ok := newCertPool.AppendCertsFromPEM(pem); !ok {
		return err
	}
	...
}

使用相对路径(./certs/cert1.pem)引用此文件是行不通的,因为Go使用可执行文件的工作目录来解析相对路径,而导入的模块位于完全不同的位置。

无论将此模块导入到何处,我如何加载与可移植模块捆绑的.pem文件?

英文:

I'm trying to create a portable Go module that will be re-used in many different projects. This module, in order to function, needs to be able to read non-Go files that are bundled as part of the module. In this case, they're some certificate bundles. The selection of which file to load is dynamic and based on input arguments.

What is the best way to specify the path to these files when loading them? I can't seem to find any Go functions to get a path relative to the module (vs. relative to the executable that is using this module). For example, if my module structure looks like this:

mymodule/
  go.mod
  go.sum
  loadcerts.go
  certs/
    cert_A.pem
    cert_B.pem

And I need to do something like this:

// loadcerts.go

package mymodule

func LoadCerts(useB bool) error {
	newCertPool := x509.NewCertPool()

    // This is just to show that the selection is dynamic, and since
    // there are many different potential files to load, we can't 
    // embed them all
    bundleName := "cert_A.pem"
    if useB {
        bundleName = "cert_B.pem"
    }
	pem, err := ioutil.ReadFile(fmt.Sprintf("./certs/%s", bundleName))
	if err != nil {
		return err
	}
	if ok := newCertPool.AppendCertsFromPEM(pem); !ok {
		return err
	}
	...
}

Referencing this file with a relative path (./certs/cert1.pem) doesn't work, since Go uses the executable's working directory for relative paths, and this imported module is somewhere entirely different.

How can I load this .pem file that is bundled with the portable module, regardless of where this module is being imported to?

答案1

得分: 3

将文件嵌入可执行文件作为文件系统:

//go:embed certs
var f embed.FS

从文件系统中读取文件:

pem, err := f.ReadFile(fmt.Sprintf("certs/%s", bundleName))
英文:

Embed the files in the executable as a file system:

//go:embed certs
var f embed.FS

Read the files from the file system:

pem, err := f.ReadFile(fmt.Sprintf("certs/%s", bundleName))

huangapple
  • 本文由 发表于 2022年2月8日 01:01:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/71022412.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定