【发布时间】:2018-11-07 18:28:28
【问题描述】:
写入不存在的文件不会在 Go 中产生错误。
例如,下面是一个循环写入文件的示例程序:
package main
import (
"log"
"os"
"time"
)
func main() {
f, err := os.OpenFile("mytest.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
for {
n, err := f.WriteString("blah\n")
if err != nil {
log.Fatal(err)
}
log.Printf("wrote %d bytes\n", n)
time.Sleep(2 * time.Second)
}
}
当它运行时,我从命令行发出rm mytest.log 并观察到程序在下一次调用WriteString() 时不会产生错误。 (我在Linux上测试过,其他操作系统可能不同)
有没有办法检测文件是否被删除(除了在每次写入之前对文件进行统计)?并且大概写入的字节被操作系统简单地丢弃了?
【问题讨论】:
-
字节不会被丢弃。您可以倒退到文件的开头并将其读回。创建文件然后立即取消链接是处理临时文件的常见模式。
-
这是因为您使用 os.Openfile() 打开一个端口并写入该特定端口,在写入操作期间不再执行错误检查。因此,在写入操作期间您不会收到文件未找到错误。
-
在大多数 Unix 文件系统上,删除文件只会删除 inode 条目,使底层文件保持完整,直到它被关闭。这是一个功能,在某些情况下可以发挥很大的优势,但是 TL;DR;是:您所描述的情况是故意的。
-
也许您应该解释为什么您关心文件是否被删除,以便我们提出适当的对策。只要您不关闭()文件,所有 *os.File 方法都应该 JustWork(tm)。仅当您开始按名称引用文件时才会遇到问题,但每次这样做时,您都必须处理(甚至!)错误。
标签: go