fswatch

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 22, 2015 License: BSD-3-Clause, BSD-3-Clause Imports: 5 Imported by: 0

README

fswatch

fswatch is a go library for recursively watching file system changes to does not depend on inotify and therefore is not limit by the ulimit of your operating system.

Motivation

Why not use inotify? Even though there are great libraries like fsnotify that offer cross platform file system change notifications - the approach breaks when you want to watch a lot of files or folder.

For example the default ulimit for Mac OS is set to 512. If you need to watch more files you have to increase the ulimit for open files per process. And this sucks.

Usage

Watching a single file

If you want to watch a single file use the NewFileWatcher function to create a new file watcher:

go func() {
	checkIntervalInSeconds := 2
	fileWatcher := fswatch.NewFileWatcher("Some-file", checkIntervalInSeconds).Start()

	for fileWatcher.IsRunning() {

		select {
		case <-fileWatcher.Modified:

			go func() {
				// file changed. do something.
			}()

		case <-fileWatcher.Moved:

			go func() {
				// file moved. do something.
			}()
		}

	}
}()
Watching a folder

To watch a whole folder (and all of its child directories) for new, modified or deleted files you can use the NewFolderWatcher function.

Parameters:

  1. The path to the directory you want to monitor
  2. A flag indicating whether the folder shall be watched recursively
  3. An expression which decides which files are skipped
  4. The check interval in seconds (1 - n seconds)
go func() {

	recurse := true // include all sub directories

	skipDotFilesAndFolders := func(path string) bool {
		return strings.HasPrefix(filepath.Base(path), ".")
	}

	checkIntervalInSeconds := 2

	folderWatcher := fswatch.NewFolderWatcher(
		"some-directory",
		recurse,
		skipDotFilesAndFolders,
		checkIntervalInSeconds
	)
	
	folderWatcher.Start()

	for folderWatcher.IsRunning() {

		select {

		case <-folderWatcher.Modified():
			fmt.Println("New or modified items detected")

		case <-folderWatcher.Moved():
			fmt.Println("Items have been moved")

		case changes := <-folderWatcher.ChangeDetails():

			fmt.Printf("%s\n", changes.String())
			fmt.Printf("New: %#v\n", changes.New())
			fmt.Printf("Modified: %#v\n", changes.Modified())
			fmt.Printf("Moved: %#v\n", changes.Moved())

		}
	}

}()

go-fswatch in action

You can see go-fswatch in action in the live-reload feature of my markdown webserver "allmark".

See: github.com/andreaskoch/allmark/blob/master/src/allmark.io/modules/dataaccess/filesystem/watcher.go

I would still prefer using inotify, but go-fswatch has been doing it's job in allmark pretty well and works easily with relatively large folder structures.

Build Status

Build Status

Contribute

All contributions are welcome. Especially if you have an idea

  • how to reliably increase the limit for the maximum number of open files from within an application so we can use inotify for large folder structures.
  • how to overcome the limitations of inotify without having to resort to checking the files for changes over and over again
  • or how to make the existing code more efficient

please send me a message or a pull request.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DisableDebug

func DisableDebug()

DisableDebug disables the debug mode for this package and closes the debug message channel.

func EnableDebug

func EnableDebug() chan string

EnableDebug enables the debug mode for this package and returns a debug message channel.

func NumberOfFileWatchers

func NumberOfFileWatchers() int

NumberOfFileWatchers returns the number of currently active file watchers.

func NumberOfFolderWatchers

func NumberOfFolderWatchers() int

NumberOfFolderWatchers returns the number of currently active folder watchers.

Types

type FileWatcher

type FileWatcher struct {
	// contains filtered or unexported fields
}

A FileWatcher can be used to determine if a given file has been modified or moved.

func NewFileWatcher

func NewFileWatcher(filePath string, checkIntervalInSeconds int) *FileWatcher

NewFileWatcher creates a new file watcher for a given file path. The check interval in seconds defines how often the watcher shall check for changes (recommended: 1 - n seconds).

func (*FileWatcher) IsRunning

func (fileWatcher *FileWatcher) IsRunning() bool

IsRunning returns a flag indicating whether the watcher is currently running.

func (*FileWatcher) Modified

func (filewatcher *FileWatcher) Modified() chan bool

Modified returns a channel indicating if the file has been modified.

func (*FileWatcher) Moved

func (filewatcher *FileWatcher) Moved() chan bool

Moved returns a channel indicating if the file has been moved.

func (*FileWatcher) SetFile

func (fileWatcher *FileWatcher) SetFile(filePath string)

SetFile sets the file file for this file watcher.

func (*FileWatcher) Start

func (fileWatcher *FileWatcher) Start()

Start starts the watch process.

func (*FileWatcher) Stop

func (fileWatcher *FileWatcher) Stop()

Stop stops the watch process.

func (*FileWatcher) Stopped

func (filewatcher *FileWatcher) Stopped() chan bool

Stopped returns a channel indicating if the file watcher stopped.

func (*FileWatcher) String

func (fileWatcher *FileWatcher) String() string

type FolderChange

type FolderChange struct {
	// contains filtered or unexported fields
}

FolderChange represents changes (new, moved and modified items) of a folder at a given time.

func (*FolderChange) Modified

func (folderChange *FolderChange) Modified() []string

Modified returns the modified items of the current folder change.

func (*FolderChange) Moved

func (folderChange *FolderChange) Moved() []string

Moved returns the moved items of the current folder change.

func (*FolderChange) New

func (folderChange *FolderChange) New() []string

New returns the new items of the current folder change.

func (*FolderChange) String

func (folderChange *FolderChange) String() string

func (*FolderChange) TimeStamp

func (folderChange *FolderChange) TimeStamp() time.Time

TimeStamp retunrs the time stamp of the current folder change.

type FolderWatcher

type FolderWatcher struct {
	// contains filtered or unexported fields
}

A FolderWatcher can be used to watch a folder for modified or moved items.

func NewFolderWatcher

func NewFolderWatcher(folderPath string, recurse bool, skipFile func(path string) bool, checkIntervalInSeconds int) *FolderWatcher

NewFolderWatcher creates a new folder watcher for the given folder path. The recurse flag indicates whether the watcher shall include sub folders of the the given folder path. The skipFile expression can be used to exclude certains files or folders. The check interval in seconds defines how often the watcher shall check for changes (recommended: 1 - n seconds).

func (*FolderWatcher) ChangeDetails

func (folderWatcher *FolderWatcher) ChangeDetails() chan *FolderChange

ChangeDetails returns a model containing all changed during a given change interval.

func (*FolderWatcher) IsRunning

func (folderWatcher *FolderWatcher) IsRunning() bool

IsRunning returns a flag indicating whether the watcher is currently running.

func (*FolderWatcher) Modified

func (folderWatcher *FolderWatcher) Modified() chan bool

Modified returns a channel indicating if the current folder has been modified.

func (*FolderWatcher) Moved

func (folderWatcher *FolderWatcher) Moved() chan bool

Moved returns a channel indicating if the current folder has been moved.

func (*FolderWatcher) Start

func (folderWatcher *FolderWatcher) Start()

Start starts the watch process.

func (*FolderWatcher) Stop

func (folderWatcher *FolderWatcher) Stop()

Stop stops the watch process.

func (*FolderWatcher) Stopped

func (folderWatcher *FolderWatcher) Stopped() chan bool

Stopped returns a channel indicating if current folder watcher stopped.

func (*FolderWatcher) String

func (folderWatcher *FolderWatcher) String() string

type Watcher

type Watcher interface {

	// Modified returns a boolean channel which sends a flag indicating
	// whether a filesystem item has been modified.
	Modified() chan bool

	// Moved returns a boolean channel which sends a flag indicating
	// whether a filesystem item has moved.
	Moved() chan bool

	// Stopped returns a boolean channel which sends a flag indicating
	// whether the filesystem watcher has stopped.
	Stopped() chan bool

	// Start starts the watch-process.
	Start()

	// Stop stops any the watch-process.
	Stop()

	// IsRunning returns a flag indicating whether this
	// filesystem watcher is running or not.
	IsRunning() bool
}

Watcher defines the base set of of functions for a file and folder watcher.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL