为什么写入已删除的文件不会在 Go 中返回错误?

Ste*_*ven 0 file go

即使该程序正在写入已删除的文件,它也能成功运行。为什么这样做?

package main

import (
    "fmt"
    "os"
)

func main() {
    const path = "test.txt"

    f, err := os.Create(path) // Create file
    if err != nil {
        panic(err)
    }

    err = os.Remove(path) // Delete file
    if err != nil {
        panic(err)
    }

    _, err = f.WriteString("test") // Write to deleted file
    if err != nil {
        panic(err)
    }

    err = f.Close()
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("No errors occurred") // test.txt doesn't exist anymore
}
Run Code Online (Sandbox Code Playgroud)

max*_*_ge 5

在类 Unix 系统上,当一个进程打开一个文件时,它会得到一个File descriptor指向进程File table条目的 ,而该条目又是指磁盘上的inode 结构。inode保留文件信息,包括data location.

目录的内容只是成对的 inode 编号和名称。

如果你删除一个文件,你只需inode从目录中删除一个指向inode它的链接,它仍然存在(只要没有从某个地方指向它的链接,包括进程),并且可以从/向 读取和写入数据data location。

在 Windows 上,此代码失败,因为 Windows 不允许删除打开的文件:

panic: remove test.txt: The process cannot access the file because it is being used by another process.
goroutine 1 [running]:
main.main()
D:/tmp/main.go:18 +0x1d1
exit status 2
Run Code Online (Sandbox Code Playgroud)