Golang 生成带扩展名的唯一文件名

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


Von*_*onC 7

更新(2020 年:原始答案来自 2015 年)

Lax回答所述,Go 1.11(2018 年 4 月)已将TempFile前缀更改 为模式。

提交191efbcCL 105675问题4896

用户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

  • 您肯定需要的不仅仅是该功能。例如,该函数可以返回已经存在的文件名。这样的 API 应该通过用`O_CREAT | 打开文件来创建文件。O_EXCL` 以确保在决定名称和创建文件之间没有其他人创建文件。 (4认同)