在Go语言中,资源应该存放在哪里?

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

Where should resources be kept in golang

问题

你的应用程序使用JSON配置文件和其他资源。我应该把它们放在项目层次结构的哪个位置?

我在http://golang.org/doc/code.html(如何编写Go代码)中没有找到答案。

更新:
这个问题不是关于自动分发应用程序资源的,而是更简单的:我应该把资源放在项目层次结构的哪个位置?有没有一些标准的位置可以放置这些资源?

英文:

My application uses json configuration files and other resources. Where should I place them in my project hierarchy?
I could not find the answer in http://golang.org/doc/code.html (How to Write Go Code)

Upd:
The question is not about automatic distribution of resources with application but much simpler: Where should I keep my resources in project hierarchy? Is there some standard place anyone expects them to be?

答案1

得分: 13

没有单一正确的答案,也没有任何强制性的约定,也没有任何Go工具在此时假设或强制执行。

通常,我会假设我需要的文件位于程序运行的同一目录中。例如,假设我需要myprog.goconf.json文件;那么这两个文件就在同一个目录中,可以运行以下命令:

go build -o myprog && ./myprog

当我部署代码时,myprog二进制文件和conf.json文件在服务器上放在一起。运行/监控脚本需要cd到该目录,然后运行程序。

当你有很多资源时,这也适用;例如,如果你有一个包含JS、CSS和图像的Web服务器,你只需假设它们相对于代码中的cwd,并将资源目录与服务器二进制文件一起部署。

另一种不假设cwd的方法是使用-conf标志,用户可以使用该标志指定配置文件。我通常在分发命令行工具和需要单个配置文件的开源服务器应用程序中使用这个方法。如果需要,你甚至可以使用-assets标志或其他标志来指向一个完整的资源文件树。

最后,还有一种方法是不使用任何资源文件。go-bindata是一个我曾经用过的有用工具,它将一些数据编码为字节并嵌入到Go源文件中。这样,所有资源都被编译到二进制文件中。我认为这种方法在资源数据很少或几乎不会改变,并且资源数据很小的情况下最有用。(否则,你将会传输巨大的二进制文件。)我过去使用go-bindata的一个(有点愚蠢的)例子是将favicon嵌入到一个非常简单的服务器中,除了服务器二进制文件之外,不需要任何额外的文件。

英文:

There is no single correct answer, nor are there any strong conventions assumed or enforced by any Go tooling at this time.

Typically I start by assuming that the files I need are located in the same directory from where the program will be run. For instance, suppose I need conf.json for myprog.go; then both of those files live together in the same directory and it works to just run something like

go build -o myprog && ./myprog

When I deploy the code, the myprog binary and conf.json live together on the server. The run/supervisor script needs to cd to that directory and then run the program.

This also works when you have a lot of resources; for instance, if you have a webserver with JS, CSS, and images, you just assume they're relative to cwd in the code and deploy the resource directories along with the server binary.

Another alternative to assuming a cwd is to have a -conf flag which the user can use to specify a configuration file. I typically use this for distributing command-line tools and open-source server applications that require a single configuration file. You could even use an -assets flag or something to point to a whole tree of resource files, if you wanted.

Finally, one more approach is to not have any resource files. go-bindata is a useful tool that I've used for this purpose -- it just encodes some data as bytes into a Go source file. That way it's all baked into your binary. I think this method is most useful when the resource data will rarely or never change, and is pretty small. (Otherwise you're going to be shipping around huge binaries.) One (kind of silly) example of when I've used go-bindata in the past was for baking a favicon into a really simple server which didn't otherwise require any extra files besides the server binary.

答案2

得分: 1

对于静态资源,将它们包含在二进制文件中可能是最方便的解决方案,类似于Java中的资源。较新的Go版本,至少1.18版本,提供了//go:embed指令来包含内容:

import (
	_ "embed"
)

//go:embed myfile.txt
var myfile string

现在你可以在代码中使用myfile了。例如,IntelliJ也支持这一功能。

还有其他选项可以包含内容,例如作为二进制文件或动态加载,请参考链接。

英文:

For static resource it might be the most convenient solution to include them in the binary similar to resources in Java. Newer Go version, at least 1.18 are providing the //go:embed directive to include content:

import (
	_ "embed"
)

//go:embed myfile.txt
var myfile string

You can now use myfile in your code. E.g. IntelliJ provides also support for this.

There are also other options to include the content, e.g. as binary or dynamically, see the link.

huangapple
  • 本文由 发表于 2013年10月25日 18:03:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/19586827.html
匿名

发表评论

匿名网友

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

确定