用Go获取文件的inode

11

如何在Go语言中获取文件 inode?

我已经可以像这样打印它:

file := "/tmp/system.log"
fileinfo, _ := os.Stat(file)
fmt.Println(fileinfo.Sys())
fmt.Println(fileinfo)

查看Go实现代码,很明显需要寻找stat方法,但我仍未能找到Unix系统结构的定义。

如何直接获取inode值?

源代码中哪个或哪些文件定义了Sys()的结构?

3个回答

22
你可以使用类型断言来从fileinfo中获取底层的syscall.Stat_t,方法如下:
package main

import (
    "fmt"
    "os"
    "syscall"
)

func main() {
    file := "/etc/passwd"
    fileinfo, _ := os.Stat(file)
    fmt.Printf("fileinfo.Sys() = %#v\n", fileinfo.Sys())
    fmt.Printf("fileinfo = %#v\n", fileinfo)
    stat, ok := fileinfo.Sys().(*syscall.Stat_t)
    if !ok {
        fmt.Printf("Not a syscall.Stat_t")
        return
    }
    fmt.Printf("stat = %#v\n", stat)
    fmt.Printf("stat.Ino = %#v\n", stat.Ino)
}

忽略调用上面的os.Stat(file)时出现的错误并不是一个好主意,特别是当被搜索的文件可能根本不存在时。如果您在未检查的情况下解引用fileinfo,则可能会导致运行时恐慌。我知道这只是一个例子,但如果使用上述模型,人们可能会遇到问题。 - Randy Howard
stat, ok := fileinfo.Sys().(*syscall.Stat_t) 这行代码实际上是做什么的?根据 fmt.Printf("%T", fileinfo.Sys())fileinfo.Sys() 返回一个 *syscall.Stat_t。希望能够提供一些解释。 - Brettski
1
@Brettski:fileinfo.Sys()会返回一个interface{}值,可能是nil,它捕获了底层系统调用中os.Stat()的结果。stat, ok := fileinfo.Sys().(*syscall.Stat_t)这一行是一个类型断言,它表示我认为这个接口值里面是一个*syscall.Stat_t。如果是的话,就让我拿到它,并将变量ok设置为true 如果ok为真,则stat现在有了您期望的指针(如果!ok,则stat为nil),您现在可以使用stat.Ino和其他类似的字段。 - torek
@Brettski,为了进一步解释@torek所说的内容:在与操作系统进行接口时,Go必须在两个相互排斥的要求之间取得平衡:一方面,它在其标准库中提供的API应该努力成为100%同构(跨平台),另一方面,程序员经常需要掌握琐碎的特定于平台的细节。这就是为什么os.(* Fileinfo).Stat()返回“任何类型”的值——interface {}:返回值的确切(动态)类型是特定于操作系统的,程序员需要断言其真实类型以获得正确类型的值。 - kostix
@Brettski,例如,在Windows上,os.(*FileInfo).Sys()返回*syscall.Win32FileAttributeData——您可以通过运行$ GOOS=windows go doc syscall.Win32FileAttributeData来了解它。 - kostix

11

你可以做以下事情:

file := "/tmp/system.log"
var stat syscall.Stat_t
if err := syscall.Stat(file, &stat); err != nil {
    panic(err)
}
fmt.Println(stat.Ino)

你要查找的 stat.Ino 是inode。


-1

1
有没有使用该软件包进行此操作的示例? - user5359531

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