Embedding Files into Your Go Program

July 30, 2023

In this blog post, we will delve into the process of embedding files into a Go program, a process which can prove quite useful in a variety of contexts. From adding configuration files, HTML templates, to images, and other static assets, the concept of file embedding provides the ability to bundle these files directly into your Go binary. This makes distribution of your application significantly easier as you no longer have to worry about file paths or distributing additional files along with your executable.

Since Go 1.16, Go includes a package called 'embed' which simplifies the process of embedding files and directories. Let's look at how we can use this package effectively.

Step 1: Importing the embed package

First, you'll need to import the embed package into your Go program. The import statement should look like this:

import _ "embed"

 Note that the underscore (_) is used because we won't be using the package directly in our code.

Step 2: Embedding a single file

 If you want to embed a single file, such as a text or a configuration file, you'll have to declare a global variable with a special comment immediately above it:

//go:embed hello.txt
var s string

In this case, 'hello.txt' is the name of the file we want to embed and 's' is the variable that will hold the contents of the file as a string.

Step 3: Accessing the embedded file

Now that you have the contents of the file, you can use it like you would use a regular string:

fmt.Println(s)

This will print the contents of the 'hello.txt' file.

Step 4: Embedding multiple files

The 'embed' package also provides a way to embed multiple files by using the FS (file system) type. This type represents a read-only collection of files. Here is how you can use it:

//go:embed hello.txt world.txt
var f embed.FS

In this case, both 'hello.txt' and 'world.txt' files are embedded into the 'f' variable.

Step 5: Accessing the embedded files

To access the files embedded into the FS variable, you can use the Open method:

file, _ := f.Open("hello.txt")
bytes, _ := ioutil.ReadAll(file)
fmt.Println(string(bytes))

In this example, we're opening 'hello.txt', reading all its contents into a byte slice, and then converting that slice into a string to print it.

Step 6: Embedding directories

You can also embed entire directories. This is especially useful for static assets like images, CSS, or JavaScript files:

//go:embed static
var staticFiles embed.FS

In this case, all the files in the 'static' directory will be embedded into the 'staticFiles' variable.

Step 7: Accessing the embedded directory

To access files in the embedded directory, you just need to include the directory name in the path:

file, _ := staticFiles.Open("static/hello.txt")
bytes, _ := ioutil.ReadAll(file)
fmt.Println(string(bytes))

 In this example, we're opening 'hello.txt' from the 'static' directory, reading all its contents, and then printing it.

Conclusion

Embedding files into your Go program is a powerful tool to bundle your static assets, configuration files, or other necessary files directly into your Go binary. This makes it easier to distribute your application and avoids potential issues with file paths and missing files. The Go 'embed' package is a fantastic addition to the Go standard library, making file embedding a straightforward and efficient process. 

Read also

Discovering Go: A Deep Dive into Google's Own Programming Language
How to Create Linked Lists in Go
Implementing a TCP Client and Server in Go: A Ping Pong Example
Implementing rate limiters in the Echo framework
Go random uint8 and uint16
Golang human readable byte sizes
Comments
Tags