惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Heimdal Security Blog
SecWiki News
SecWiki News
H
Hacker News: Front Page
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
AI
AI
C
Cybersecurity and Infrastructure Security Agency CISA
Scott Helme
Scott Helme
PCI Perspectives
PCI Perspectives
S
Securelist
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Cyberwarzone
Cyberwarzone
A
Arctic Wolf
Forbes - Security
Forbes - Security
T
Tor Project blog
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
I
Intezer
Martin Fowler
Martin Fowler
Help Net Security
Help Net Security
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
博客园 - 司徒正美
W
WeLiveSecurity
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
V2EX
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
V
Vulnerabilities – Threatpost
Jina AI
Jina AI
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
Simon Willison's Weblog
Simon Willison's Weblog
Project Zero
Project Zero
T
Threatpost
P
Privacy International News Feed
人人都是产品经理
人人都是产品经理
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research

MoonLab

VSCode + OpenOCD 远程调试开发STM32 Clangd + VSCode使用方法 Keil5 编译错误 error: call to undeclared function '__enable_irq' BTSNOOP is FUN! 算法 - 前缀和 2025蓝桥杯赛后总结 三星ZFold 3改造 JavaScript 逆向 Steam 登录二维码 快速求解平方根倒数算法 Protobuf Android设备安装Debian成为BT下载服务器 [双系统] Windows 更新摧毁了我的Linux系统 Reading List Hexo博客自动备份插件 云盘备份支持 通过汇编分析栈、函数调用 esp&ebp Git push 出现 permisson denied error 403 坑:Litepal save方法返回true却没有保存 Android Shizuku源码分析 第二篇 Android Shizuku源码分析 Android 监听第三方Activity的一举一动 Android笔记#1 View的事件分发机制解析 知乎日报的问题 使用Hexo Hello World Ubnutu 无法启动网易云音乐 - 总结 Windows 好软推荐 | 这一定是良心软件 typecho - http转https 如何评价Android P MoonLab MoonLab MoonLab 关于 项目
Golang embed 使用问题
LingC · 2023-12-27 · via MoonLab

📦 由AI生成的摘要
Golang 使用 embed 包在编译时将外部文件包含到二进制程序中。使用 embed 指令可以将 html、css、js 等静态文件添加到二进制文件中,而无需额外的资源文件。嵌入文件可以使用字符串、[]字节和 FS 来引用。但也有一些限制,如文件层次结构问题和复杂路径问题。例如,如果嵌入文件和被嵌入文件不在同一层次,嵌入模式将无法成功解析。另一个问题是处理复杂路径,即静态文件夹被放置在嵌入文件的子文件夹中。解决办法是使用 io/fs 软件包中的 Sub 方法来处理这些复杂路径。

Golang一般用到embed package的主要场景就是Web server需要携带html css js等静态文件。

使用embed directive可以让外部文件在编译时自动加入到二进制程序中。这样我们如果要分发程序,只需一个二进制文件,不需要外带任何其他资源文件。

而我们在代码中去引用embedded文件有三种方法(类型):string , []byteFS

但实际上,embed还是有一些限制的,本文就详细讲讲这些限制是什么,以及如何曲线救国。

文件层级问题

如果embed directive与被embedded的文件不在同一级(文件系统中)。

比如说

│  main.go
│  
├─server
│      handler.go
│      
└─tepl
        index.html

如果handler.go试图去包含tepl文件夹里的文件:

// handler.go
//go:embed tepl
var s embed.FS

embed pattern将无法被成功解析,因为被引用者的文件层级高于引用者。

除了将被引用者的文件层级降至同一级或更低,还有一种方法就是直接在main.go这样同级的文件中进行处理,然后传递给需要的包中。

// main.go
//go:embed tepl
var tepl embed.FS

func main() {
	handler.injectFS(&tepl)
}

目前来说,没有其他更好的解决方法了。

复杂路径问题

假如我们在tepl中放入一个static文件夹:

│  main.go
│  
└─server
    │  handler.go
    │  
    └─tepl
        │  index.html
        │  
        └─static
                main.css

在handler.go中,我们用http.FileServer来处理对静态文件们的请求:

//go:embed tepl
var tepl embed.FS

func handle() {
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(tepl))))
}

很自然地,定义的是/static/的路由,而不是/,因为根路径常常要处理其他事情。

但此时由于 embed 的局限,如果我们要获取mian.css,就需要访问这个路径/static/tepl/static/main.css

解决的方法也很简单,用 io.fs 包中的Sub方法即可:

var tepl embed.FS

func handle() {
	sub, _ := fs.Sub(tepl, "tepl/static")
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(sub))))
}

Refs


https://pkg.go.dev/embed