The upcoming Golang 1.16 release adds native support for embedding files into your binaries with the new embed
package.
Using it is very straightforward and simple.
Let's say we have the following file structure:
$ tree .
.
├── assets
│ ├── hello.txt
│ ├── index.html
│ ├── style.css
│ └── template.html
├── go.mod
├── hello.txt
└── main.go
We can embed the a single file like this:
1package main
2
3import (
4 _ "embed"
5 "fmt"
6)
7
8func main() {
9
10 //go:embed "hello.txt"
11 var s string
12 fmt.Println(s)
13
14}
This will put the content of hello.txt
in the string variable called s
during compilation. If you prefer the file to be embedded as a byte array, you simply change the data type of your variable:
1package main
2
3import (
4 _ "embed"
5 "fmt"
6)
7
8func main() {
9
10 //go:embed "hello.txt"
11 var b []byte
12 fmt.Println(string(b))
13
14}
You can also embed it using the new FS
type so that we can read it as a filesystem. This allows you to embed multiple files or a complete file tree at once:
1package main
2
3import (
4 "embed"
5 "fmt"
6)
7
8func main() {
9
10 //go:embed hello.txt
11 var f embed.FS
12 data, _ := f.ReadFile("hello.txt")
13 fmt.Println(string(data))
14
15}
We can also use the filesystem type to render templates:
1package main
2
3import (
4 "embed"
5 "fmt"
6 "html/template"
7 "log"
8 "os"
9)
10
11//go:embed assets
12var assets embed.FS
13
14func main() {
15
16 tmpl, err := template.ParseFS(assets, "assets/template.html")
17 if err != nil {
18 log.Fatal(err)
19 }
20
21 if err := tmpl.Execute(os.Stdout, map[string]string{
22 "title": "My Title",
23 "message": "Hello World",
24 }); err != nil {
25 log.Fatal(err)
26 }
27
28}
One last trick, you can also use it in combination with a webserver:
1package main
2
3import (
4 "embed"
5 "fmt"
6 "net/http"
7)
8
9//go:embed assets
10var assets embed.FS
11
12func main() {
13
14 fmt.Println("http://localhost:8080/assets/index.html")
15 fs := http.FileServer(http.FS(assets))
16 http.ListenAndServe(":8080", fs)
17
18}
You can read all the details about this in the documentation.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.