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.

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

Тип переменной должен быть типом string, или срезом типа byte, или 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/*’ или символическим ссылкам. Шаблоны не должны соответствовать файлам, имена которых содержат специальные знаки препинания " * < > ? ` ' | / \ и :. Соответствия пустым каталогам игнорируются. После этого каждый шаблон в строке //go:embed должен соответствовать, по крайней мере, одному файлу или непустому каталогу.

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

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

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

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

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

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

FS реализует интерфейс io/fs package's 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
  • функция (f FS) Open(name string) (fs.File, ошибка)
  • функция (f FS) ReadDir(name string) ([]fs.DirEntry, ошибка)
  • функция (f FS) ReadFile(name string) ([]байт, ошибка)

Примеры

Пакет

Файлы пакета

embed.go

тип FS 1.16

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

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

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

См. документацию пакета для получения более подробной информации об инициализации FS.

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

функция (FS) Open 1.16

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

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

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

функция (FS) ReadDir 1.16

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

ReadDir читает и возвращает весь указанный каталог.

функция (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