2013-09-29 76 views
6

使用Go時,我正在編寫一個小型實用程序,部分需要注意打開文件的文件名是否更改。下面的代碼說明了我想盡了辦法:如何檢測Golang中打開文件的文件名更改

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

這只是開始無休止循環,運行file.Stat()獲得每5秒文件的詳細信息,然後打印出了名。但是,儘管在運行時更改了文件名,但上述內容的輸出不會改變。

替換details.Name()與確實會注意到文件大小的變化。

這僅僅是我的Go版本中的錯誤,還是我只是在做錯事情?我無法在任何地方找到這樣的問題。

我在Mac上運行此版本,使用Go版本1.1.1(darwin/amd64)。

預先感謝任何答覆:)

+1

[fsnotify](https://github.com/howeyc/fsnotify)可能會幫助你。 –

回答

4

在類Unix操作系統上,一旦你打開一個文件,它就不再與名字綁定了。你得到的文件描述符只與你打開的文件的inode有關。文件的所有元數據都與inode相關聯。沒有簡單的方法可以從inode獲取文件的名稱,因此除非您正在使用的操作系統提供了一種特殊的方法,否則您想要的是不可能的。

另外:你想觀察什麼文件名?一個文件可能有多個名字或根本沒有名字(比如一個典型的臨時文件)。

我想你可以做的唯一的事情是:

  • 打開文件時,請記住文件名
  • 定期調用統計上的文件名,看看這個inode是否匹配
  • 如果inode不同,您的文件已被移動

然而,這並沒有給你新的文件名。這樣的事情是不可能做到的。

2

唉這是一個相當困難的問題找到一般打開的文件的名稱。

所有file.Name()確實是這樣的(see the docs

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

你可能想看看這個問題的一些想法:Getting Filename from file descriptor in C。答案中有針對Linux,Windows和Mac的解決方案。

+0

如上所述,如果文件被重命名,則file.Name()不會更改。我認爲這個答案沒有解決OP問的問題。 – fuz

+0

這個問題解釋了爲什麼Name()不會改變。我認爲文檔中的引用很好地回答了這個問題! –