Fsnotify — библиотека Go для кроссплатформенных уведомлений о файловой системе
Fsnotify — это библиотека Go, предоставляющая кроссплатформенные уведомления о файловой системе на Windows, Linux, macOS, BSD и illumos. Требуется Go 1.17 или более новая версия; полная документация доступна по ссылке: https://pkg.go.dev/github.com/fsnotify/fsnotify.
Поддержка платформ:
Бэкенд | ОС | Статус |
---|---|---|
inotify | Linux | Поддерживается |
kqueue | BSD, macOS | Поддерживается |
ReadDirectoryChangesW | Windows | Поддерживается |
FEN | illumos | Поддерживается |
fanotify | Linux 5.9+ | Пока нет |
AHAFS | AIX | [ветка aix]; экспериментальная из-за отсутствия сопровождающего и тестовой среды |
FSEvents | macOS | Требуется поддержка в x/sys/unix |
USN Journals | Windows | Требуется поддержка в x/sys/windows |
Polling | Все | Пока нет |
Linux и illumos должны включать Android и Solaris, но они в настоящее время не протестированы.
Пример:
package main
import (
"log"
"github.com/fsnotify/fsnotify"
)
func main() {
// Create new watcher.
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
// Start listening for events.
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
log.Println("event:", event)
if event.Has(fsnotify.Write) {
log.Println("modified file:", event.Name)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Println("error:", err)
}
}
}()
// Add a path.
err = watcher.Add("/tmp")
if err != nil {
log.Fatal(err)
}
// Block main goroutine forever.
<-make(chan struct{})
}
Дополнительные примеры можно найти в cmd/fsnotify, который можно запустить с помощью команды:
% go run ./cmd/fsnotify
Более подробную документацию можно найти в godoc: https://pkg.go.dev/github.com/fsnotify/fsnotify.
Нет, если вы не следите за местом, куда он был перемещён.
Нет, необходимо добавлять часы для любого каталога, который вы хотите отслеживать (рекурсивный наблюдатель находится в планах: #18).
Да. Вы можете читать оба канала в одной горутине, используя select
(вам не нужна отдельная горутина для обоих каналов; см. пример).
Fsnotify требует поддержки со стороны базовой ОС. Текущие протоколы NFS и SMB не обеспечивают поддержку уведомлений на сетевом уровне, как и виртуальные файловые системы /proc и /sys.
Это можно исправить с помощью наблюдателя опроса (#9), но он ещё не реализован.
Некоторые... Программы могут генерировать множество изменений атрибутов. Например, известно, что Spotlight на macOS, антивирусные программы, приложения для резервного копирования и некоторые другие делают это. Как правило, лучше всего игнорировать события Chmod. Они часто не полезны и могут вызвать проблемы.
Индексирование Spotlight на macOS может привести к множеству событий (см. #15). Временным решением является добавление ваших папок в настройки конфиденциальности Spotlight, пока у нас не появится собственная реализация FSEvents (см. #11).
Наблюдение за отдельными файлами (а не каталогами) обычно не рекомендуется, поскольку многие программы (особенно редакторы) обновляют файлы атомарно: они записывают во временный файл, который затем перемещается в место назначения, перезаписывая оригинал (или его вариант). Наблюдатель за исходным файлом теперь потерян, так как его больше не существует.
В результате сбой питания или сбой не оставят наполовину записанный файл.
Следите за родительским каталогом и используйте Event.Name, чтобы отфильтровать файлы, которые вас не интересуют. Пример этого есть в cmd/fsnotify/file.go.
Когда файл удаляется, событие REMOVE не будет отправлено, пока все файловые дескрипторы не будут закрыты; вместо этого будет отправлено CHMOD:
fp := os.Open("file")
os.Remove("file") // CHMOD
fp.Close() // REMOVE
Это событие, которое отправляет inotify, поэтому мало что можно изменить в этом отношении.
Переменная sysctl fs.inotify.max_user_watches определяет верхний предел количества наблюдений для каждого пользователя, а fs.inotify.max_user_instances определяет максимальное количество экземпляров inotify для каждого пользователя. Каждый созданный вами Watcher является «экземпляром», а каждый добавляемый путь — «наблюдением».
Они также отображаются в /proc как /proc/sys/fs/inotify/max_user_watches и /proc/sys/fs/inotify/max_user_instances.
Чтобы увеличить их, вы можете использовать sysctl или записать значение в файл proc:
# Значения по умолчанию в Linux 5.18
sysctl fs.inotify.max_user_watches=124983
sysctl fs.inotify.max_user_instances=128
Чтобы изменения сохранились после перезагрузки, отредактируйте /etc/sysctl.conf или /usr/lib/sysctl.d/50-default.conf (детали зависят от дистрибутива Linux; обратитесь к документации вашего дистрибутива):
fs.inotify.max_user_watches=124983
fs.inotify.max_user_instances=128
Достижение предела приведёт к ошибке «нет места на устройстве» или «слишком много открытых файлов».
kqueue требует открытия файлового дескриптора для каждого файла, за которым ведётся наблюдение; поэтому, если вы наблюдаете за каталогом с пятью файлами, это шесть файловых дескрипторов. На этих платформах вы быстрее достигнете предела вашей системы «максимальное количество открытых файлов».
Для управления максимальным количеством открытых файлов можно использовать переменные sysctl kern.maxfiles и kern.maxfilesperproc.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )