Joh*_*gue 8 go temporary-files
我想在 Golang 中生成带有扩展名的唯一文件名。非常类似于 ioutil.TempFile,它只需要前缀。
这已在论坛https://groups.google.com/forum/#!topic/golang-nuts/PHgye3Hm2_0 中多次提出,Go 似乎非常打算不将该功能添加到 TempFile。
那么处理这个问题的建议方法是什么?我应该复制/粘贴 TempFile 代码并添加后缀参数吗?
小智 9
从 Go 1.16(2021 年 2 月)开始,您可以使用os.CreateTemp:
package main
import "os"
func main() {
dirs := []string{"", "."}
for _, dir := range dirs {
f, err := os.CreateTemp(dir, "*.txt")
if err != nil {
panic(err)
}
defer f.Close()
println(f.Name())
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
package main
import "os"
func main() {
dirs := []string{"", "."}
for _, dir := range dirs {
f, err := os.CreateTemp(dir, "*.txt")
if err != nil {
panic(err)
}
defer f.Close()
println(f.Name())
}
}
Run Code Online (Sandbox Code Playgroud)
https://godocs.io/os#CreateTemp
更新(2020 年:原始答案来自 2015 年)
如Lax的回答所述,Go 1.11(2018 年 4 月)已将TempFile前缀更改 为模式。
用户
TempFile需要能够提供后缀,使用操作系统上运行的文件扩展名,如Windows给语义时尤其如此。
事后重命名文件以包含扩展名是不够的,因为它可能导致竞争条件。如果给定的字符串
TempFile包含“*”,则随机字符串替换“*”。例如“
myname.*.bat”将产生一个随机的文件名,如“myname.123456.bat”。如果不
*包含" ' ,则保留旧行为,并将随机数字附加到末尾。如果多个“
*”被包括,最后一个被替换,因此允许病理程序员创建的文件名,例如“foo*.123456.bat”但不是“foo.123456.*.bat”
原始答案 (2015)
我应该复制/粘贴 TempFile 代码并添加后缀参数吗?
那将是一种方式。
另一种方法是快速 - 粗略 - 实现,如本项目:
// TempFileName generates a temporary filename for use in testing or whatever
func TempFileName(prefix, suffix string) string {
randBytes := make([]byte, 16)
rand.Read(randBytes)
return filepath.Join(os.TempDir(), prefix+hex.EncodeToString(randBytes)+suffix)
}
Run Code Online (Sandbox Code Playgroud)
正如James Henstridge 在下面评论的那样,这是一个粗略的函数:
例如,该函数可以返回已经存在的文件名。这样的 API 应该通过打开文件来创建文件,
O_CREAT | O_EXCL以确保在决定名称和创建文件之间没有其他人创建文件。
上面那个粗略的函数仅说明了rand.Read()生成文件名的用法。
但其他检查都在io/ioutil/tempfile.go.
3of3 建议在使用功能math.rand ,而不是复制的随机数发生器io/ioutil/tempfile.go。