file - 检查无效的文件描述符

标签 file go

有没有办法在 Go 中检查文件描述符是否有效(在初始打开操作之后)?

如果在命令行标志中指定,请考虑以下打开调试文件的代码片段

    upstreamDebug := flag.String("upstream_debug", "", "File for debugging")
    flag.Parse()

    var upstreamDebugFile os.File
    if *upstreamDebug != "" {
        upstreamDebugFile, err := os.OpenFile(*upstreamDebug, os.O_CREATE|os.O_WRONLY, 0644)
        if err != nil {
            log.Fatal(err)
        }
        log.Println("writing to", upstreamDebugFile.Name())
        defer upstreamDebugFile.Close()
    }

到现在为止还挺好。但稍后我们希望写信给 upstreamDebugFile , if & 仅当它是一个有效的描述符时 - 在 if { .. } 子句之外。

有没有办法测试它的有效性? lib中似乎没有任何内置方法。与零比较

    if upstreamDebugFile == nil {

给出错误
cannot convert nil to type os.File

最佳答案

根据评论:

I'm using the upstreamDebugFile value as an io.WriteCloser. I find it does not give equality with nil, even when the file is not set.



An io.WriteCloser is an instance of an interface .同时,os.OpenFile返回 *os.File ,即 a pointer to a struct .这实现了接口(interface),但不是该接口(interface)类型的值。这对某些用途来说没什么大不了的,因为它实现了接口(interface)这一事实意味着您可以存储 *os.File io.WriteCloser 中的值.

但是,正如以下程序所示,您必须小心测试 io.WriteCloser为零,因为它通常不是:
package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    var iface io.WriteCloser
    p, err := os.OpenFile("/bad/foo", os.O_CREATE, 0666)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Printf("before assignment, iface = %#v, and iface == nil => %t\n", iface, iface == nil)
    iface = p
    fmt.Printf("after assignment, iface = %#v, and iface == nil => %t\n", iface, iface == nil)
    fmt.Printf("meanwhile p == nil => %t\n", p == nil)
}

Go Playground输出:
open /bad/foo: No such file or directory
before assignment, iface = <nil>, and iface == nil => true
after assignment, iface = (*os.File)(nil), and iface == nil => false
meanwhile p == nil => true

一次iface有一个指定的类型,你不能只测试它作为一个整体。你必须开始测试它的实际值,它的底层类型,就像在这个程序中一样:
package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    var iface io.WriteCloser
    p, err := os.OpenFile("/bad/foo", os.O_CREATE, 0666)
    if err != nil {
        fmt.Println(err)
    }
    iface = p
    fmt.Printf("iface.(*os.File) == nil => %t\n", iface.(*os.File) == nil)
}

Try it on the Go Playground.但请注意,如果 iface从未分配过 *os.File 类型的值,类型断言将失败!

如果你要存储的总是*os.File ,只需将变量声明为 *os.File前面:
var foo *os.File
if somecond {
    var err error
    foo, err = os.OpenFile(... arguments ...)
    ...
}
// later:
if foo != nil {
    ...
}

请注意,您也可以这样做:
var iface io.WriteCloser
...
if somecond {
    p, err := os.OpenFile(...)
    ...
    if p != nil {
        iface = p
    }
}

现在 iface == nil又够了。但除非你真的打算使用多个不同的底层 io.WriteCloser实现,保持简单,只需使用 *os.File直接地。

关于file - 检查无效的文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58348279/

相关文章:

c - 在c中将数据从文件加载到数组

file - 移动名称中有空格的文件

c - 文件末尾后有哪些字符?

go - panic : runtime error: index out of range 1

go - Golang内置函数 "make"如何实现不同类型的参数长度检查?

google-app-engine - 如何使 golang gin 与谷歌应用程序引擎一起工作?

c - filePointer 在 while 循环中自动进行?

git - 控制 Go 包版本

Golang 预加载

ASP.NET 请求 - 我可以从客户端创建的动态控件获取发布的文件吗?