跳转到主要内容

Go 1.11 带来了一些非常酷的新功能,例如实验性的 Go Modules 功能,以及使用 ioutil 包中的新 TempFile 和 TempDir 函数创建临时文件和目录的能力。

从这些函数调用创建的临时文件和目录是全局唯一的,这很棒,因为它简化了我们在 Go 程序中处理数百甚至数千个文件的方式。

在本教程中,我们将研究如何在自己的 Go 程序和一些潜在用例中使用它们。

创建临时文件


让我们从新的 TempFile 函数开始。假设我们正在创建一个对象识别系统,它可以提取数千张汽车图片并将它们用作训练集。

对于我们拉入的每辆汽车,我们都希望创建一个具有唯一名称的临时文件,我们不一定关心。

package main

import (
    "fmt"
    "ioutil"
    "os"
)

func main() {
    // we call ioutil.TempFile which returns either a file
    // or an error.
    // we specify the directory we want to create these temp files in
    // for this example we'll use `car-images`, and we'll define
    // a pattern which will be used for naming our car images
    // in this case car-*.png
    file, err := ioutil.TempFile("car-images", "car-*.png")
    if err != nil {
        fmt.Println(err)
    }
    // We can choose to have these files deleted on program close
    defer os.Remove(file.Name())
    // We can then have a look and see the name
    // of the image that has been generated for us
    fmt.Println(file.Name())
}

如果我们尝试在控制台中运行它,我们应该会看到以下输出:

$ go run main.go
car-images/car-982382640.png


这会自动将我们定义的 car-*.png 模式中的 * 字符替换为随机的、全局唯一的模式。

写入临时文件


如果我们想写入这些临时文件,我们可以使用 Write 函数,如下所示:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    // we call ioutil.TempFile which returns either a file
    // or an error.
    // we specify the directory we want to create these temp files in
    // for this example we'll use `car-images`, and we'll define
    // a prefix that will be used for all of our individual image filenames
    // in this case we'll use 'car-'
    file, err := ioutil.TempFile("car-images", "car-*.png")
    if err != nil {
        fmt.Println(err)
    }
    // We can choose to have these files deleted on program close
    defer os.Remove(file.Name())

    if _, err := file.Write([]byte("hello world\n")); err != nil {
        fmt.Println(err)
    }

    data, err := ioutil.ReadFile(file.Name())
    // if our program was unable to read the file
    // print out the reason why it can't
    if err != nil {
        fmt.Println(err)
    }

    // if it was successful in reading the file then
    // print out the contents as a string
    fmt.Print(string(data))

}

这会将 Hello World\n 写入我们的临时文件,然后尝试使用 ioutil.ReadFile() 函数读入该文件的内容。当我们运行它时,我们应该看到以下输出:

$ go run main.go
hello world


生成临时目录


现在我们已经介绍了临时文件,让我们看看生成临时目录。如果我们想进一步扩展我们的对象识别系统并生成包含不同对象和汽车的目录,这可能很有用。

让我们看一个简单实用的示例,了解如何使用它。我们将从上面扩展我们现有的程序来创建一个临时目录,我们的临时汽车文件将存在于其中:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

func main() {

    tempDir, err := ioutil.TempDir("", "cars-")
    if err != nil {
        fmt.Println(err)
    }
    defer os.RemoveAll(tempDir)

    file, err := ioutil.TempFile(tempDir, "car-*.png")
    if err != nil {
        fmt.Println(err)
    }
    defer os.Remove(file.Name())

    // This will print out the full name and path of our image
    fmt.Println(file.Name())

    if _, err := file.Write([]byte("hello world\n")); err != nil {
        fmt.Println(err)
    }

    data, err := ioutil.ReadFile(file.Name())
    // if our program was unable to read the file
    // print out the reason why it can't
    if err != nil {
        fmt.Println(err)
    }

    // if it was successful in reading the file then
    // print out the contents as a string
    fmt.Print(string(data))

}

当我们运行它时,我们应该看到我们的全局唯一目录正在创建,并且我们的全局唯一文件名附加到该目录的末尾:

$ go run main.go
/var/folders/3x/5g0pww953x54mq7rjttr5f880000gn/T/cars-396489778/car-860960233.png
hello world


结论


太棒了,在本教程中,我们研究了如何使用 io/ioutil 包中新添加的 TempDir 和 TempFile 函数来获得名利。

您的意见对于使这些教程做到最好很重要,如果您对如何改进这些教程有任何想法/建议,那么我很乐意在下面的建议框中听到它们!

文章链接