go - go:embed 指令的问题:名称无效
问题描述
我想从我的硬盘提供音乐。所有音频文件(mp3/flac/等)都是只读的。所以使用 //go:embed 应该适用于这些文件。所以我有
//go:embed "assets/Media/Music/*"
var f embed.FS
func main() {
router := gin.Default()
router.StaticFS("/public", http.FS(f))
router.GET("/", func(c *gin.Context) {
file, _ := f.ReadFile("assets/Media/Music/<some_other_folders>/01 - my_song.mp3")
c.Data(
http.StatusOK,
"audio/mpeg",
file,
)
}
router.Run(":8080")
}
问题是 Go 编译器抱怨某些文件夹名称无效,例如:“Big KRIT”和“Al B. Sure!” 文档说文件名不应该有空格或“。” 但如果我没有明确说明文件/文件夹名称,我不知道这是否适用。
我的问题是
- 什么构成“无效名称”
- 有没有办法让嵌入指令的文件夹名称带有空格
编辑
上面的代码(几乎)正是我在本地运行的。当我尝试构建(或运行 main.go)时,VS Code 会捕获此错误。结尾是文件夹名称,而不是用于说明的文件。希望这会有所帮助。提前致谢
解决方案
查询发出错误的go
命令src :invalid name
if elem := filepath.Base(dir); isBadEmbedName(elem) {
if dir == file {
return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
} else {
return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
}
}
这引用isBadEmbedName然后依赖于函数module.CheckFilePath。此函数的文档指出:
// CheckFilePath checks that a slash-separated file path is valid.
// The definition of a valid file path is the same as the definition
// of a valid import path except that the set of allowed characters is larger:
// all Unicode letters, ASCII digits, the ASCII space character (U+0020),
// and the ASCII punctuation characters
// “!#$%&()+,-.=@[]^_{}~”.
// (The excluded punctuation characters, " * < > ? ` ' | / \ and :,
// have special meanings in certain shells or operating systems.)
//
// CheckFilePath may be less restrictive in the future, but see the
// top-level package documentation for additional information about
// subtleties of Unicode.
因此,根据最后一行,嵌入式文件名规则似乎是一个移动目标。
针对这个验证函数运行一些测试,显示出更多的微妙之处,例如dot.in.middle
vs dot.at.end.
:
https://play.golang.org/p/7x6i_Aj8eEJ
所以这可以解释为什么你的路径Big K.R.I.T.
失败了。
另外值得注意的是:当使用//go:embed
带有通配符的指令时,是否会影响编译成功。
正如您所经历的,您的编译在使用时失败:
//go:embed "assets/Media/Music/*"
var f embed.FS
由于该目录中的文件名格式无效。但是,如果您删除通配符:
//go:embed "assets/Media/Music"
var f embed.FS
编译会成功——但是任何无效的文件名都会从嵌入清单中默默地删除。
如果您想明确检查程序中将嵌入哪些文件,您可以利用go list
例如
go list -json
并查找EmbedFiles
输出部分。或者使用jq在这部分归零:
$ go list -json | jq .EmbedFiles
[
"Static Files/Space Dir/Big K.R.I.T.mp3",
"Static Files/Space Dir/world.txt",
"Static Files/hey!"
]
推荐阅读
- java - 使用 Apache Poi 从 Excel 工作表单元格的下拉列表中一次选择多个值
- c# - 微软身份授权
- aws-glue - AWS Glue-确保只有 1 个输出文件在 s3 存储桶中
- google-apps-script - 如何在下周的日期自动打开我的工作表?
- algorithm - 卡梅里尼算法找到最小瓶颈生成树,证明
- visual-studio-code - Visual Studio Code 在标题栏中显示管理员
- camtasia - Camtasia (Windows):我们很抱歉!您的录音文件有问题
- rascal - 函数签名中的模式匹配语法替代
- php - Ajax 成功调用特定引导选项卡
- python - 从字典中绘制每月天气数据