为什么os.Open在打开目录时返回nil错误?

问题描述:

我花了一些时间寻找我的代码中的错误,它似乎在一个地方,我试图读取目录的内容,就像它是文件。请看下面的代码:为什么os.Open在打开目录时返回nil错误?

import (
    "fmt" 
    "os" 
) 

func init() { 
    file, err := os.Open("/tmp/") 
    fmt.Println(file, err) //err == nil here 
    var b []byte 
    n, err := file.Read(b) 
    fmt.Println(n, err) //err == "read /tmp/: is a directory" 
} 

我很纳闷,为什么os.Open允许“开放”的目录中没有错误,如果我无法反正“读”呢?文档说

打开打开命名文件以供阅读。如果成功,可以使用 返回的文件中的方法进行读取;关联的文件描述符 具有模式O_RDONLY。如果有错误,它将是类型 * PathError。 [reference]

如果'目录'是'文件'有争议,但对我来说它看起来有点误导。这种行为有用吗?

“阅读”有更多的含义,其中之一是阅读文件的内容。

另一个含义是,如果文件表示一个目录,则可以使用File.Readdir()File.Readdirnames()来读取其内容,即其中的文件/子文件夹的列表。这对于名称表示目录的打开文件来说是完全有效的。

此外,即使它表示一个文件夹,例如打开的os.File,您也可以做更多事情。请拨打File.Chdir()(专用于目录)或File.Chmod()方法,或使用File.Stat()获取关于它的统计信息。我不明白为什么“打开”文件夹应该被禁止。文档中的措辞可能不完美(或者可以扩展到提及这个)。

+1

对,我错过了'Readdir()'方法的存在。它让这个想法变得清晰。我想这对于那些从其他语言中走出来的人来说有点违反直觉。 – Grief

+0

@遗憾同意。这应该在文档中提及。 – icza

+1

@Grief:知道打开一个目录并使用readdir是一个POSIX接口,而不依赖于特定的语言可能会很有用。由于Go根源于C和unix系统,因此往往是寻找方向的好地方。 – JimB