Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

go

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

like image 208
jsdw Avatar asked Sep 29 '13 16:09

jsdw


2 Answers

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.

like image 129
fuz Avatar answered Nov 15 '22 03:11

fuz


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.

like image 31
Nick Craig-Wood Avatar answered Nov 15 '22 03:11

Nick Craig-Wood