golangs os.Stat 打开文件吗?

til*_*boy 1 file-io go

os.Stat(path string) (os.FileInfo, error)函数是否(尝试)打开位于 的文件path,或者是否涉及任何技巧以使其不需要?

另外,多次打开/关闭文件的性能损失是什么(没有读/写,我知道这些很慢),而不是只执行一次?是硬盘绑定的吗?操作系统之间有区别吗?

aba*_*ert 5

文档并没有真正解释你为什么想要 a FileInfo,或者它是如何检索的。我怀疑他们假设大多数读者会从名称中认出它是 Unix 调用的跨平台抽象stat,并且已经知道这意味着什么。这并不是 Go 独有的——无数其他语言的标准库在文档中都有类似命名的函数和类似的假设。(例如,请参阅Python。)

stat函数的重点是无需打开文件即可获取有关文件的元数据(大小、创建时间等)。这很重要有两个原因:

  • 您可能没有打开文件的权限。
  • 仅读取元数据会更有效率(无需读取数据流、在内核的打开文件表中创建条目等)。

而且,正如您在文档中看到的,os.Stat在大多数平台上实现为statfstatat1

因此,如果您想获取文件的大小,os.Stat比打开文件、查找到最后并获取当前位置要快得多。或者甚至只是打开文件并关闭它。但它仍然不是免费的。

对于大多数 Unix 文件系统,它的工作方式是读取一个 inode,一个包含有关文件的所有关键信息的单个磁盘块,并且通常优化 inode 分配。(它还需要至少读取一个目录,因为您是按名称指定文件的,但是对于性能很重要的通常情况,扫描整个目录或树,它会被缓存。)

而且肯定存在平台差异。最大的,2和往常一样,介于 Windows 和其他所有人之间。Windows 的 NTFS 文件系统缓存目录条目中的大部分(但不是全部)相同信息,因此如果您只需要该信息,您甚至不需要转到(相当于)inode,而且速度要快得多。但如果你想要一切,它会更慢。类似find搜索目录树的工具必须针对这些差异进行优化,但对于大多数程序来说,这不是问题;只是打电话stat。或者,在 Go 中,os.Stat.


1. 那个fillFileStatFromSys让你感到困惑的函数只是将 struct 中返回的信息重新组织stat成 Go 想要呈现的格式,所以你不必处理相当于笨拙的 C 宏和遗留时间戳格式等。

2. 从历史上看,有些平台没有像 远程那样的东西stat,要模拟它,您确实必须打开和关闭文件。但我认为 Go 不会在任何这些平台上运行。