【发布时间】:2020-11-16 19:42:50
【问题描述】:
在 Go 中如何检查文件是否为硬链接? os.FileMode 只有符号链接模式,没有硬链接。
我有一个想法,可惜行不通:
package main
func main() {
filename := os.Args[1]
var hardlink bool
link, _ := os.Readlink(filename)
fi, _ := os.Stat(filename)
mode := string(fi.Mode().String()[0])
if link != "" && mode != "L" {
hardlink = true
}
fmt.Printf("%v is hard link? %v\n", filename, hardlink)
}
这个^ 不起作用,因为os.Readlink 只读取符号链接,而不是硬链接。
我找到了一个有点相关的答案:
Counting hard links to a file in Go
但是这个答案显示了如何找到文件的硬链接数量,而不是是否文件本身是硬链接。
我猜测该答案中使用的 syscall 包,或者更好的是,sys 包可以测试文件是否为硬链接。有谁知道这样做吗? (我很难理解这些包,因为它们太低级了。)
编辑
我应该添加我想检查这个的原因。我正在尝试创建一个函数来创建目录的 tar 存档 [使用filepath.Walk()]。在此函数中,当我为文件创建 *tar.Header 时,我将值设置为 *tar.Header.Typeflag。
例如,如果fi 是文件的*os.FileInfo 变量,而hdr 是该文件在新tar 归档中的位置的*tar.Header 变量,则如下所示:
if fi.Mode().IsDir() {
hdr.Typeflag = tar.TypeDir
}
在tar 包中,硬链接和常规文件的模式是不同的,TypeLink 和TypeReg,但在os 包中不是这种情况。所以运行它不会设置正确的Typeflag:
hdr.Mode = int64(fi.Mode())
【问题讨论】:
-
每个常规文件都是硬链接。指向同一个 inode 的两个硬链接之间没有区别,只是它们的名称不同。
-
删除文件的系统调用称为“取消链接”是有原因的。 (另外,golang.org/x/sys 包只是 syscall 包加上更新,因为 stdlib 系统调用被冻结了)
-
老实说,我以前从来没有这样想过。这清楚了很多。我正在更新我的答案以显示我想检查这个的原因。
标签: file go attributes hardlink