为了账号安全,请及时绑定邮箱和手机立即绑定

读取刚刚写入临时文件的数据

读取刚刚写入临时文件的数据

Go
湖上湖 2022-07-04 16:57:46
在 Go 中,我试图将数据写入一个临时文件,然后我转身阅读但没有成功。下面是一个精简的测试程序。我已经通过检查临时文件验证了数据是否正在写入文件。所以,至少我知道数据正在进入文件中。我只是无法读出来。提前谢谢你的帮助package mainimport (    "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)    }}
查看完整描述

2 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

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


另外,作为一个好习惯,不要忘记关闭文件。请注意,我使用defer tmpFile.Close()了在退出之前关闭文件的方法。


请参考以下示例:


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 的评论:


鉴于删除实际文件也被延迟,是否需要延迟关闭?如果是这样,我想延期的顺序很重要。


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


如果您参考C++ 的文档:


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


因此,在 Windows 上,如果您先尝试删除它而不关闭它,那肯定会出现问题。


所以,因为defer's 是堆叠的,所以执行的顺序是


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

defer tmpFile.Close() // Called 1st


查看完整回答
反对 回复 2022-07-04
?
桃花长相依

TA贡献1860条经验 获得超8个赞

package main


import (

    "fmt"

    "io/ioutil"

    "log"

)


func main() {

    content, err := ioutil.ReadFile("testdata/hello")

    if err != nil {

        log.Fatal(err)

    }


    fmt.Printf("File contents: %s", content)

根据 golang 官方文档。


查看完整回答
反对 回复 2022-07-04
  • 2 回答
  • 0 关注
  • 149 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号