带有必须阅读的捆绑文件的便携式 Go 模块
Portable Go module with bundled files that must be read
我正在尝试创建一个可移植的 Go 模块,它将在许多不同的项目中重复使用。为了运行,该模块需要能够读取作为模块一部分捆绑的非 Go 文件。在这种情况下,它们是一些证书包。选择要加载的文件是动态的,并且基于输入参数。
加载这些文件时指定路径的最佳方法是什么?我似乎找不到任何 Go 函数来获取相对于模块的路径(相对于 using 这个模块的可执行文件)。例如,如果我的模块结构如下所示:
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()
// 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
}
...
}
用相对路径 (./certs/cert1.pem
) 引用这个文件是行不通的,因为 Go 使用可执行文件的工作目录作为相对路径,而这个导入的模块在某个地方完全不同。
如何加载与便携式模块捆绑在一起的这个 .pem
文件,而不考虑将此模块导入到何处?
Embed作为文件系统的可执行文件中的文件:
//go:embed certs
var f embed.FS
从文件系统读取文件:
pem, err := f.ReadFile(fmt.Sprintf("certs/%s", bundleName))
我正在尝试创建一个可移植的 Go 模块,它将在许多不同的项目中重复使用。为了运行,该模块需要能够读取作为模块一部分捆绑的非 Go 文件。在这种情况下,它们是一些证书包。选择要加载的文件是动态的,并且基于输入参数。
加载这些文件时指定路径的最佳方法是什么?我似乎找不到任何 Go 函数来获取相对于模块的路径(相对于 using 这个模块的可执行文件)。例如,如果我的模块结构如下所示:
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()
// 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
}
...
}
用相对路径 (./certs/cert1.pem
) 引用这个文件是行不通的,因为 Go 使用可执行文件的工作目录作为相对路径,而这个导入的模块在某个地方完全不同。
如何加载与便携式模块捆绑在一起的这个 .pem
文件,而不考虑将此模块导入到何处?
Embed作为文件系统的可执行文件中的文件:
//go:embed certs
var f embed.FS
从文件系统读取文件:
pem, err := f.ReadFile(fmt.Sprintf("certs/%s", bundleName))