读取刚刚写入临时文件的数据 [英] Reading data just written to a temp file

查看:60
本文介绍了读取刚刚写入临时文件的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Go中,我试图将数据写入一个临时文件,然后我转过身来读取并没有成功.以下是精简的测试程序.我已经通过检查临时文件验证了数据已写入文件中.因此,至少我知道数据正在将其放入文件中.那只是我无法读出来.

In Go, I am trying to write data to a temp file that I then turn around and read but have not been successful. Below is a stripped down test program. I have verified that the data are being written to the file by inspecting the temporary file. So, at least I know that data are making it into the file. I just am then unable to read it out.

谢谢您的帮助

package main

import (
    "bufio"
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
)

func main() {

    tmpFile, err := ioutil.TempFile("", fmt.Sprintf("%s-", filepath.Base(os.Args[0])))
    if err != nil {
        log.Fatal("Could not create temporary file", err)
    }
    fmt.Println("Created temp file: ", tmpFile.Name())
    //  defer os.Remove(tmpFile.Name())

    fmt.Println("Writing some data to the temp file")
    if _, err = tmpFile.WriteString("test data"); err != nil {
        log.Fatal("Unable to write to temporary file", err)
    } else {
        fmt.Println("data should have been written")
    }

    fmt.Println("Trying to read the temp file now")
    s := bufio.NewScanner(tmpFile)
    for s.Scan() {
        fmt.Println(s.Text())
    }
    err = s.Err()
    if err != nil {
        log.Fatal("error reading temp file", err)
    }
}

推荐答案

ioutil.TempFile 创建一个临时文件并打开该文件进行读写,并返回生成的 * os.File(文件描述符).因此,当您在文件内部进行写入时,指针将移动到该偏移量,即当前位于文件末尾.但是,当从文件中读取您的要求时,您需要使用 * os.File.Seek 方法将 Seek 回到起始位置或所需的偏移量.因此,添加 tmpFile.Seek(0,0)将为您提供所需的行为.

ioutil.TempFile creates a temp file and opens the file for reading and writing and returns the resulting *os.File (file descriptor). So when you're writing inside the file, the pointer is moved to that offset, i.e., it's currently at the end of the file. But as your requirement is read from the file, you need to Seek back to the beginning or wherever desired offset using *os.File.Seek method. So, adding tmpFile.Seek(0, 0) will give you the desired behaviour.

此外,作为一种好的做法,请不要忘记关闭文件.请注意,我已经使用 defer tmpFile.Close()在退出前关闭文件.

Also, as a good practice, do not forget to close the file. Notice I've used defer tmpFile.Close() which closes the file before exiting.

请参考以下示例:

package main

import (
    "bufio"
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
)

func main() {
    tmpFile, err := ioutil.TempFile("", fmt.Sprintf("%s-", filepath.Base(os.Args[0])))
    if err != nil {
        log.Fatal("Could not create temporary file", err)
    }
    defer tmpFile.Close()

    fmt.Println("Created temp file: ", tmpFile.Name())

    fmt.Println("Writing some data to the temp file")
    if _, err = tmpFile.WriteString("test data"); err != nil {
        log.Fatal("Unable to write to temporary file", err)
    } else {
        fmt.Println("Data should have been written")
    }

    fmt.Println("Trying to read the temp file now")

    // Seek the pointer to the beginning
    tmpFile.Seek(0, 0)
    s := bufio.NewScanner(tmpFile)
    for s.Scan() {
        fmt.Println(s.Text())
    }
    if err = s.Err(); err != nil {
        log.Fatal("error reading temp file", err)
    }
}

更新:OP的评论:

考虑到删除实际文件也被推迟了,是否需要推迟关闭?如果是这样,我想推迟的顺序会很重要.

Is the deferred close needed given that deleting the actual file is also deferred? If so, I imagine order of deferral would matter.

所以,这是一个很好的问题.因此,基本的经验法则是关闭文件然后删除.因此,甚至有可能先删除它,然后再将其关闭,但这取决于操作系统.

So, that's a nice question. So the basic rule of thumb would be to close the file and then remove. So, it might even be possible to delete first and later close it, but that is OS-dependent.

如果您引用 C ++的文档:

如果当前正在由当前进程或其他进程打开文件,则此功能的行为由实现定义(特别是POSIX系统取消链接文件名,尽管即使最后一个文件系统空间也没有被回收)硬链接到文件,直到最后一个运行的进程关闭该文件,Windows不允许删除该文件)

If the file is currently open by the current or another process, the behavior of this function is implementation-defined (in particular, POSIX systems unlink the file name, although the file system space is not reclaimed even if this was the last hardlink to the file until the last running process closes the file, Windows does not allow the file to be deleted)

因此,在Windows上,如果您先尝试将其删除而不关闭它,那肯定是个问题.

So, on Windows, that's a problem for sure if you try deleting it first without closing it.

因此,由于 defer 的堆叠,因此执行顺序为

So, as defer's are stacked, so the order of execution would be

defer os.Remove(tmpFile.Name()) // Called 2nd
defer tmpFile.Close() // Called 1st

这篇关于读取刚刚写入临时文件的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆