Documentation
¶
Overview ¶
Package watchfs implement naive file and directory watcher.
Index ¶
Examples ¶
Constants ¶
const FileFlagDeleted = -1
FileFlagDeleted indicated that a file has been deleted. The flag is stored inside the os.FileInfo.Size.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DirWatcher ¶
type DirWatcher struct { // C received the new, updated, and deleted files. C <-chan []os.FileInfo // contains filtered or unexported fields }
DirWatcher scan the content of directory in watchfs.DirWatcherOptions.Root recursively for the files to be watched, using the watchfs.DirWatcherOptions.Includes field. A single file, watchfs.DirWatcherOptions.File, will be watched for changes that will trigger re-scanning the content of Root recursively.
The result of re-scanning is list of the Includes files (only files not new directory) that are changes, which will be send to channel C. On each os.FileInfo received from C, a deleted file have os.FileInfo.Size equal to FileFlagDeleted. The channel will send an empty slice if no changes.
The implementation of file changes in this code is naive, using loop and comparison of mode, modification time, and size; at least it should works on most operating system.
func WatchDir ¶
func WatchDir(opts DirWatcherOptions) (dwatch *DirWatcher, err error)
WatchDir create and start scanning directory for changes.
Example ¶
var ( dirTemp string err error ) dirTemp, err = os.MkdirTemp(``, ``) if err != nil { log.Fatal(err) } var ( fileToWatch = filepath.Join(dirTemp, `.rescan`) opts = watchfs.DirWatcherOptions{ FileWatcherOptions: watchfs.FileWatcherOptions{ File: fileToWatch, Interval: 50 * time.Millisecond, }, Root: dirTemp, Includes: []string{`.*\.adoc$`}, Excludes: []string{`exc$`, `.*\.html$`}, } dwatch *watchfs.DirWatcher ) dwatch, err = watchfs.WatchDir(opts) if err != nil { log.Fatal(err) } var ( fileAadoc = filepath.Join(opts.Root, `a.adoc`) fileBadoc = filepath.Join(opts.Root, `b.adoc`) fileAhtml = filepath.Join(opts.Root, `a.html`) ) err = os.WriteFile(fileAadoc, nil, 0600) if err != nil { log.Fatal(err) } err = os.WriteFile(fileAhtml, nil, 0600) if err != nil { log.Fatal(err) } err = os.WriteFile(fileBadoc, nil, 0600) if err != nil { log.Fatal(err) } // Write to the file that we watch for changes to trigger rescan. err = os.WriteFile(fileToWatch, []byte(`x`), 0600) if err != nil { log.Fatal(err) } var changes []os.FileInfo = <-dwatch.C var names []string for _, fi := range changes { // Since we use temporary directory, print only the base // name to make it works on all system. names = append(names, filepath.Base(fi.Name())) } sort.Strings(names) fmt.Println(names)
Output: [a.adoc b.adoc]
func (*DirWatcher) Files ¶
func (dwatch *DirWatcher) Files() (files map[string]os.FileInfo)
Files return all the files currently being watched, the one that filtered by watchfs.DirWatcherOptions.Includes, with its file information. This method is not safe when called when DirWatcher has been running.
func (*DirWatcher) ForceRescan ¶
func (dwatch *DirWatcher) ForceRescan()
ForceRescan force to rescan for changes without waiting for watchfs.DirWatcherOptions.File to be updated.
func (*DirWatcher) Stop ¶
func (dwatch *DirWatcher) Stop()
Stop watching the file and re-scanning the Root directory.
type DirWatcherOptions ¶
type DirWatcherOptions struct { FileWatcherOptions // The root directory where files to be scanned. Root string // List of regex for files or directories to be excluded from // scanning. // The Excludes option will be processed before Includes. Excludes []string // List of regex for files or directories to be included from // scanning. Includes []string // contains filtered or unexported fields }
DirWatcherOptions contains options to watch directory.
type FileWatcher ¶
type FileWatcher struct { // C receive new file information. C <-chan os.FileInfo // contains filtered or unexported fields }
FileWatcher watch a single file. It will send the os.FileInfo to the channel C when the file is created, updated; or nil if file has been deleted.
The FileWatcher may stop unexpectedly when the os.Stat return an error other than os.ErrNotExist. The last error can be inspected using FileWatcher.Err.
func WatchFile ¶
func WatchFile(opts FileWatcherOptions) (fwatch *FileWatcher)
WatchFile watch the file watchfs.FileWatcherOptions.File for being created, updated, or deleted; on every watchfs.FileWatcherOptions.Interval.
Example ¶
var ( name = `file.txt` opts = watchfs.FileWatcherOptions{ File: filepath.Join(os.TempDir(), name), Interval: 50 * time.Millisecond, } ) fwatch := watchfs.WatchFile(opts) // On create ... _, err := os.Create(opts.File) if err != nil { log.Fatal(err) } var fi os.FileInfo = <-fwatch.C fmt.Printf("file %q created\n", fi.Name()) // On update ... err = os.WriteFile(opts.File, nil, 0600) if err != nil { log.Fatal(err) } fi = <-fwatch.C fmt.Printf("file %q updated\n", fi.Name()) // On delete ... err = os.Remove(opts.File) if err != nil { log.Fatal(err) } fi = <-fwatch.C fmt.Printf("file deleted: %v\n", fi) fwatch.Stop()
Output: file "file.txt" created file "file.txt" updated file deleted: <nil>
func (*FileWatcher) Err ¶
func (fwatch *FileWatcher) Err() error
Err return the last error that cause the watch stopped.
type FileWatcherOptions ¶
type FileWatcherOptions struct { // Path to the file to be watched. File string // Interval to check for file changes. Interval time.Duration }
FileWatcherOptions define the options to watch file.