临时文件是一个程序运行时才创建,程序结束后就无用的文件。这就延伸出了一个很重要的点:不管创建的临时文件是否已经存在,程序都应该以读写的方式打开,也就是一旦打开,就会抹除原来的内容;程序结束时就无用的文件,这就需要在程序结束时自动删除。
现在的操作系统都提供了临时文件夹,临时文件夹的意思,就是重启操作系统后,里面的内容可能会被删除的目录。
但是,这个删除操作并不总是会发生的。
因为创建和读写临时文件这么频繁,因此,大部分的操作系统都提供了相关的 API 来创建和读写临时文件,同时,大部分语言内置的标准库也提供了相关的方法或模块来创建和读写文件。
临时目录
各个操作系统都提供了一个或几个文件夹用于保存临时文件,也就是说调用系统提供的临时文件操作函数都会在这几个目录下创建临时文件。
-
Windows 系统上,临时目录由环境变量
%TMP%
,%TEMP%
,%USERPROFILE%
指定。一般情况下,这个临时目录是 C:\Users[用户名]\AppData\Local\Temp -
Linux / macOS 系统上,临时目录由
$TMPDIR
环境变量指定,如果没有设置,那么这个临时目录是/tmp
。
在 Go 语言中,包 os
提供了函数 os.TempDir()
返回当前操作系统下的临时目录。
其次 io/ioutil
包也提供了 ioutil.TempDir()
函数用于在指定目录中创建一个临时文件夹。该函数的原型如下
func TempDir(dir, prefix string) (name string, err error)
如果未指定 dir
,那么会自动调用 os.TempDir()
返回的临时目录作为跟目录。
临时文件名
使用系统相关 API ,我们是无法指定临时文件名的。仔细想想也对,这个文件我们几乎只需要读写一次,一旦创建和打开,获得了文件句柄,我们就没理由需要这个文件名了。
但为了调试目的,一般情况下,创建临时文件的函数和方法都可以让用户自己定制一个文件名前缀。
Go 语言创建临时文件
临时文件也是一个普通文件,当我们获得了临时目录后,可以调用普通的文件函数来创建和读写临时文件。
当然了,一般情况下我们不会这么做,而是调用 io/ioutil
包提供的 ioutil.TempFile()
文件来创建一个临时文件。
该函数的原型如下
func TempFile(dir, pattern string) (f *os.File, err error)
dir
参数用于指定临时文件保存的文件夹,如果为空字符串,那么会自动调用 os.TempDir()
返回的临时目录作为目录。而 pattern
用于指定临时文件的文件名格式。
patter
是一个类似正则表达式的文件名格式,可以使用 *
代表随机字符串的位置。如果 pattern
中没有 *
号,那么会自动将随机字符串添加到文件名的末尾
该函数返回一个 os.File
类型的文件指针,我们可以使用该类型提供的各种函数读写该文件。
例外需要注意的是,虽然系统可能会自动删除临时文件,但这并不一定会发生,所以,使用完毕之后记得调用 os.Remove(tmpfile.Name())
来删除临时文件,当然了,前面一般添加 defer
关键字,如下
defer os.Remove(tmpfile.Name())
使用方式
-
在临时目录中创建一个以指定字符串开始的临时文件。下面的语句创建一个以
simple
开头的临时文件tmpfile, err := ioutil.TempFile("", "simple")
-
在临时目录中创建一个以指定格式为文件名的临时文件。例如下面的语句创建一个以
simple
开头,以.txt
结尾的临时文件。系统会自动把*
号替换为随机字符串tmpfile, err := ioutil.TempFile("", "simple.*.txt")
范例
下面的范例在系统临时文件夹下创建一个以 prefix
开头的临时文件,并写入字符串 This is a www.twle.cn example!
。使用完之后调用 os.Remove()
函数删除临时文件。
package main import ( "io/ioutil" "log" "os" "fmt" ) func main() { // Create our Temp File tmpFile, err := ioutil.TempFile(os.TempDir(), "prefix-") if err != nil { log.Fatal("Cannot create temporary file", err) } fmt.Println("Created File: " + tmpFile.Name()) // Example writing to the file _, err = tmpFile.Write([]byte("This is a www.twle.cn example!")) if err != nil { log.Fatal("Failed to write to temporary file", err) } // Remember to clean up the file afterwards defer os.Remove(tmpFile.Name()) }