Spec-Zone.ru › Go

Пакет embed

  • import "embed"
  • Обзор
  • Указатель
  • Примеры

Обзор

Пакет embed предоставляет доступ к файлам, встроенным в работающую программу Go.

Исходные файлы Go, импортирующие "embed", могут использовать директиву //go:embed для инициализации переменной типа string, []byte или FS содержимым файлов, считанных из каталога пакета или его подкаталогов во время компиляции.

Например, ниже показаны три способа встроить файл с именем hello.txt, а затем вывести его содержимое во время выполнения программы.

Встраивание одного файла в строку:

import _ "embed"

//go:embed hello.txt
var s string
print(s)

Встраивание одного файла в срез байтов:

import _ "embed"

//go:embed hello.txt
var b []byte
print(string(b))

Встраивание одного или нескольких файлов в файловую систему:

import "embed"

//go:embed hello.txt
var f embed.FS
data, _ := f.ReadFile("hello.txt")
print(string(data))

Директивы

Директива //go:embed перед объявлением переменной указывает, какие файлы следует встроить, с помощью одного или нескольких шаблонов path.Match.

Директива должна непосредственно предшествовать строке с объявлением одной переменной. Между директивой и объявлением допускаются только пустые строки и построчные комментарии ‘//’.

Тип переменной должен быть строковым типом, срезом байтового типа или FS (либо псевдонимом FS).

Например:

package server

import "embed"

// content holds our static web server content.
//go:embed image/* template/*
//go:embed html/index.html
var content embed.FS

Система сборки Go распознает директивы и позаботится о том, чтобы объявленная переменная (в приведенном выше примере — content) была заполнена файлами файловой системы, соответствующими шаблону.

Для краткости директива //go:embed может принимать несколько разделенных пробелами шаблонов, но ее также можно повторять, чтобы избежать слишком длинных строк при большом количестве шаблонов. Шаблоны интерпретируются относительно каталога пакета, содержащего исходный файл. В качестве разделителя пути используется косая черта, даже в системах Windows. Шаблоны не могут содержать ‘.’, ‘..’ или пустые элементы пути, а также начинаться или заканчиваться косой чертой. Чтобы сопоставить все содержимое текущего каталога, используйте ‘*’ вместо ‘.’. Чтобы можно было указывать имена файлов с пробелами, шаблоны можно записывать в виде строковых литералов Go в двойных кавычках или обратных кавычках.

Если шаблон задает каталог, встраиваются все файлы в поддереве этого каталога (рекурсивно), за исключением файлов, имена которых начинаются с ‘.’ или ‘_’. Таким образом, переменная в приведенном выше примере почти эквивалентна следующей:

// content is our static web server content.
//go:embed image template html/index.html
var content embed.FS

Разница в том, что ‘image/*’ встраивает ‘image/.tempfile’, а ‘image’ — нет. Ни один из шаблонов не встраивает ‘image/dir/.tempfile’.

Если шаблон начинается с префикса ‘all:’, правило обхода каталогов изменяется: в него включаются файлы, начинающиеся с ‘.’ или ‘_’. Например, ‘all:image’ встраивает и ‘image/.tempfile’, и ‘image/dir/.tempfile’.

Директива //go:embed может использоваться как с экспортируемыми, так и с неэкспортируемыми переменными — в зависимости от того, хочет ли пакет сделать данные доступными другим пакетам. Ее можно использовать только с переменными уровня пакета, но не с локальными переменными.

Шаблоны не должны соответствовать файлам за пределами модуля пакета, например ‘.git/*’, символическим ссылкам, 'vendor/' или каталогам, содержащим go.mod (это отдельные модули). Шаблоны не должны соответствовать файлам, имена которых содержат специальные знаки пунктуации " * < > ? ` ' | / \ и :. Совпадения с пустыми каталогами игнорируются. После этого каждый шаблон в строке //go:embed должен соответствовать как минимум одному файлу или непустому каталогу.

Если какие-либо шаблоны недопустимы или им соответствуют недопустимые элементы, сборка завершится с ошибкой.

Строки и байты

Строка //go:embed для переменной типа string или []byte может содержать только один шаблон, и этот шаблон может соответствовать только одному файлу. Строка или []byte инициализируется содержимым этого файла.

Для директивы //go:embed требуется импортировать "embed", даже если используется string или []byte. В исходных файлах, где нет ссылок на embed.FS, используйте пустой импорт (import _ "embed").

Файловые системы

Для встраивания одного файла обычно лучше всего подходит переменная типа string или []byte. Тип FS позволяет встраивать дерево файлов, например каталог со статическим содержимым веб-сервера, как в примере выше.

FS реализует интерфейс FS пакета io/fs, поэтому его можно использовать с любым пакетом, поддерживающим файловые системы, включая net/http, text/template и html/template.

Например, используя переменную content из приведенного выше примера, можно написать:

http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content))))

template.ParseFS(content, "*.tmpl")

Инструменты

Для поддержки инструментов, анализирующих пакеты Go, шаблоны из строк //go:embed доступны в выводе “go list”. См. поля EmbedPatterns, TestEmbedPatterns и XTestEmbedPatterns в выводе команды “go help list”.

Пример

Код:

package embed_test

import (
    "embed"
    "log"
    "net/http"
)

//go:embed internal/embedtest/testdata/*.txt
var content embed.FS

func Example() {
    mux := http.NewServeMux()
    mux.Handle("/", http.FileServer(http.FS(content)))
    err := http.ListenAndServe(":8080", mux)
    if err != nil {
        log.Fatal(err)
    }
}

Указатель

  • тип FS
  • func (f FS) Open(name string) (fs.File, error)
  • func (f FS) ReadDir(name string) ([]fs.DirEntry, error)
  • func (f FS) ReadFile(name string) ([]byte, error)

Примеры

Пакет

Файлы пакета

embed.go

тип FS 1.16

FS — это доступная только для чтения коллекция файлов, обычно инициализируемая директивой //go:embed. Если FS объявлена без директивы //go:embed, она представляет собой пустую файловую систему.

FS — это значение, доступное только для чтения, поэтому его безопасно одновременно использовать из нескольких горутин, а также присваивать друг другу значения типа FS.

FS реализует fs.FS, поэтому его можно использовать с любым пакетом, поддерживающим интерфейсы файловых систем, включая net/http, text/template и html/template.

Дополнительные сведения об инициализации FS см. в документации пакета.

type FS struct {
    // contains filtered or unexported fields
}

func (FS) Open 1.16

func (f FS) Open(name string) (fs.File, error)

Open открывает указанный файл для чтения и возвращает его как fs.File.

Возвращенный файл реализует io.Seeker и io.ReaderAt, если файл не является каталогом.

func (FS) ReadDir 1.16

func (f FS) ReadDir(name string) ([]fs.DirEntry, error)

ReadDir читает и возвращает содержимое указанного каталога целиком.

func (FS) ReadFile 1.16

func (f FS) ReadFile(name string) ([]byte, error)

ReadFile читает и возвращает содержимое указанного файла.

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/embed/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API