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

huangapple go评论89阅读模式
英文:

Why os.Open returns nil error when opening a directory?

问题

我花了一些时间查找我的代码中的错误,结果发现在一个地方,我试图像读取文件一样读取目录的内容。请考虑以下代码:

import (
	"fmt"
	"os"
)

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

我想知道为什么 os.Open 允许无错误地“打开”一个目录,但无法“读取”它呢?文档中说:

Open 打开指定的文件用于读取。如果成功,返回的文件可以用于读取;关联的文件描述符具有 O_RDONLY 模式。如果出现错误,它将是 *PathError 类型。[参考链接]

对于这个“目录”是否是“文件”的问题可以有争议,但对我来说,它看起来有点误导。这种行为有什么用途吗?

英文:

I've spend some time looking for an error in my code and it appeared that at one place I was trying to read contents of a directory like it was the file. Consider the following code:

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"
}

I am wondering, why os.Open allows to 'open' a directory without an error if I cannot 'read' it anyway? The documentation says

> Open opens the named file for reading. If successful, methods on the
> returned file can be used for reading; the associated file descriptor
> has mode O_RDONLY. If there is an error, it will be of type
> *PathError. [reference]

If the 'directory' is a 'file' is disputable but for me it looks a bit misleading. Is there any usage for that behavior?

答案1

得分: 4

"Reading"有更多的含义,其中之一是读取文件的内容。

另一个含义是,如果文件表示一个目录,你可以读取它的内容,也就是其中的文件列表或子文件夹列表,可以使用File.Readdir()File.Readdirnames()。对于表示目录的已打开文件,这是完全有效的。

此外,即使文件表示一个文件夹,你也可以对已打开的os.File执行更多操作,例如调用其File.Chdir()(仅适用于目录)或File.Chmod()方法,或者使用File.Stat()获取有关它的统计信息。我不明白为什么应该禁止“打开”一个文件夹。文档中的措辞可能不完美(或者可以扩展以提及这一点)。

英文:

"Reading" has more meanings, one of which is reading the contents of a file.

Another meaning is if the file denotes a directory, you may read its content, which is the list of the files / subfolders in it, using File.Readdir() or File.Readdirnames(). This is perfectly valid for an opened file whose name denotes a directory.

Also you may do a lot more with an opened os.File even if it denotes a folder, e.g. call its File.Chdir() (exclusive for directories) or File.Chmod() methods, or get statistics about it using File.Stat(). I don't see why "opening" a folder should be disallowed. The wording in the doc may not be perfect (or it could be extended to mention this though).

huangapple
  • 本文由 发表于 2017年7月14日 22:59:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/45106090.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定