确定 *File 指向文件还是目录的 Golang 方法

53

有没有办法确定我的 *File 是指向文件还是目录?

fileOrDir, err := os.Open(name)
// How do I know whether I have a file or directory?

我希望能够读取文件的统计信息,如果它只是一个文件,而如果它是一个目录,则希望能够读取目录中的文件。

fileOrDir.Readdirnames(0) // If dir
os.Stat(name) // If file
5个回答

83
例如,
package main

import (
    "fmt"
    "os"
)

func main() {
    name := "FileOrDir"
    fi, err := os.Stat(name)
    if err != nil {
        fmt.Println(err)
        return
    }
    switch mode := fi.Mode(); {
    case mode.IsDir():
        // do directory stuff
        fmt.Println("directory")
    case mode.IsRegular():
        // do file stuff
        fmt.Println("file")
    }
}

注意:

该示例是针对Go 1.1的。对于Go 1.0,请将case mode.IsRegular():替换为case mode&os.ModeType == 0:


40

这里还有另外一种可能:

import "os"

func IsDirectory(path string) (bool, error) {
    fileInfo, err := os.Stat(path)
    if err != nil{
      return false, err
    }
    return fileInfo.IsDir(), err
}

4
请注意:目录必须存在。 - davidhq
1
如果给定的路径不存在,这会导致段错误。在返回之前添加if err != nil { return false, nil}以使其更安全。 - Alexander

17

以下是如何在一行中进行测试的方法:

    if info, err := os.Stat(path); err == nil && info.IsDir() {
       ...
    }

3
fileOrDir, err := os.Open(name)
if err != nil {
  ....
}
info, err := fileOrDir.Stat()
if err != nil {
  ....
}
if info.IsDir() {
   .... 
} else {
   ...
}

注意不要通过文件名打开和启动文件。这会产生潜在的安全问题竞争条件。

如果你的打开成功了,那么你就有了一个有效的文件句柄,并且应该使用它上面的Stat()方法来获取stat信息。顶部答案存在风险,因为他们建议首先调用os.Stat(),然后再调用os.Open(),但是在两次调用之间可能会有人更改文件。


1
multiple-value fileOrDir.Stat() in single-value context 的意思是“在单值上下文中使用多值fileOrDir.Stat()”。 - kubanczyk
使用以下代码获取文件或目录的信息:info,err:=fileOrDir.Stat(),然后可以通过判断info.IsDir()来确定其是否为目录。 - xhdix

1
import "os"

// FileExists reports whether the named file exists as a boolean
func FileExists(name string) bool {
    if fi, err := os.Stat(name); err == nil {
        if fi.Mode().IsRegular() {
            return true
        }
    }
    return false
}

// DirExists reports whether the dir exists as a boolean
func DirExists(name string) bool {
    if fi, err := os.Stat(name); err == nil {
        if fi.Mode().IsDir() {
            return true
        }
    }
    return false
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接