在Golang中,如何检测打开文件的文件名更改?

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

How do I detect a change to the filename of an open file in Golang

问题

使用Go语言,我正在编写一个小型实用程序,其中一部分需要注意打开文件的文件名是否发生更改。下面的代码演示了我尝试的方法:

package main

import "os"
import "fmt"
import "time"

func main() {

    path := "data.txt"
    file, _ := os.Open(path)

    for {
        details, _ := file.Stat()
        fmt.Println(details.Name())
        time.Sleep(5 * time.Second)
    }
}

这段代码只是启动一个无限循环,每隔5秒运行file.Stat()来获取文件的详细信息,然后打印出文件名。然而,尽管在运行过程中更改了文件名,上述代码的输出并不会改变。

details.Name()替换为details.Size()可以注意到文件大小的变化。

这只是我的Go版本中的一个错误吗,还是我做错了什么?我无法立即找到有关这个问题的任何提及。

我在Mac上运行这个程序,使用的是Go版本1.1.1(darwin/amd64)。

提前感谢您的回复 在Golang中,如何检测打开文件的文件名更改?

英文:

Using Go, I was writing a small utility that in part needs to notice if the filename of an open file changes. The below code illustrates the approach I tried:

package main

import "os"
import "fmt"
import "time"
    
func main() {

	path := "data.txt"
	file, _ := os.Open(path)

	for {
		details, _ := file.Stat()
		fmt.Println(details.Name())
		time.Sleep(5 * time.Second)
	}
}

This just starts an endless loop, running file.Stat() to obtain file details every 5 seconds and then printing out the name. However, despite changing the filename as this is running, the output of the above does not change.

replacing details.Name() with details.Size() does however notice changes to the filesize.

Is this simply a bug in my version of Go, or am I just doing things wrong? I cannot find mention of such an issue anywhere offhand.

I am running this on a Mac, with Go version 1.1.1 (darwin/amd64).

Thanks in advance for any replies 在Golang中,如何检测打开文件的文件名更改?

答案1

得分: 4

在类Unix操作系统中,一旦你打开一个文件,它就不再与一个名称绑定。你得到的文件描述符只与你打开的文件的inode绑定。文件的所有元数据都与inode相关联。没有简单的方法可以从inode获取文件名,所以你想要的是不可能的,除非你使用的操作系统提供了特殊的手段来实现这一点。

另外:你想要观察哪个文件名?一个文件可以有多个名称,或者根本没有名称(比如典型的临时文件)。

我认为你唯一能做的事情是:

  • 打开文件,记住文件名
  • 定期调用文件名的Stat函数,查看inode是否匹配
  • 如果inode不同,说明你的文件已经被移动了

然而,这并不能给你新的文件名。这样的事情在可移植性上是不可能的。

英文:

On Unix-like operating systems, once you open a file it is no longer tied to a name. The file-descripter you get is only tied to the inode of the file you open. All meta-data of a file is associated with the inode. There is no simple way to get the name of a file from the inode, thus what you want is impossible, except if the operating system you are using provides a special means to do that.

Also: What filename do you want to observe? A file could have multiple names or no name at all (such as a typical temporary file).

The only thing I think you could do is:

  • Open the file, remember the filename
  • periodically call Stat on the filename to see whether the inode matches
  • if the inode is different, your file has been moved

This does however, not give you the new filename. Such a thing is impossible to do portably.

答案2

得分: 2

哎呀,一般情况下找到一个打开文件的名称是一个相当困难的问题。

file.Name() 只是返回文件的名称,具体实现可以参考文档

你可能想看看这个问题的一些想法:从文件描述符中获取文件名。在答案中有针对 Linux、Windows 和 Mac 的解决方案。

英文:

Alas it is quite a difficult problem to find the name of an open file in general.

All file.Name() does is this (see the docs)

// Name returns the name of the file as presented to Open.
func (f *File) Name() string { return f.name }

You might want to check out this question for some ideas: Getting Filename from file descriptor in C. There are solutions for Linux, Windows and Mac in the answers.

huangapple
  • 本文由 发表于 2013年9月30日 00:40:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/19080535.html
匿名

发表评论

匿名网友

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

确定