Следите за изменениями в папке с помощью node.js и распечатывайте пути к файлам при их изменении.

87

Я пытаюсь написать сценарий node.js, который отслеживает изменения в каталоге файлов, а затем печатает файлы, которые были изменены. Как я могу изменить этот сценарий, чтобы он следил за каталогом (а не за отдельным файлом) и печатал имена файлов в каталоге по мере их изменения?

var fs = require('fs'),
    sys = require('sys');
var file = '/home/anderson/Desktop/fractal.png'; //this watches a file, but I want to watch a directory instead
fs.watchFile(file, function(curr, prev) {
    alert("File was modified."); //is there some way to print the names of the files in the directory as they are modified?
});
Андерсон Грин
источник
Интересно, актуально ли это: stackoverflow.com/questions/12063266/… (хотя я не знаком с gruntjs - надеюсь, есть другие решения.)
Андерсон Грин
Возможно, что-то вроде node-inotify-plusplus было бы полезно: stackoverflow.com/questions/5877263/…
Андерсон Грин
Какая у вас ОС? Это имеет значение, поскольку низкоуровневые механизмы просмотра файла сильно отличаются от того, что используется в Unix / Linux, используется inotifyOSX, FSWatchи я понятия не имею о Windoze, но уверен, что Google может вам сказать.
srquinn
1
Хотя изначально я использовал равнину node-inotifyв своем проекте, в конечном итоге я перешел на node-inotify-plusplusнее, потому что кому не нравятся абстракции? =)
srquinn 04

Ответы:

145

Попробуйте Чокидар :

var chokidar = require('chokidar');

var watcher = chokidar.watch('file or dir', {ignored: /^\./, persistent: true});

watcher
  .on('add', function(path) {console.log('File', path, 'has been added');})
  .on('change', function(path) {console.log('File', path, 'has been changed');})
  .on('unlink', function(path) {console.log('File', path, 'has been removed');})
  .on('error', function(error) {console.error('Error happened', error);})

Chokidar решает некоторые кроссплатформенные проблемы с просмотром файлов, используя только fs.

мтср
источник
3
Он обрабатывает подпапки?
Степан Яковенко
1
Одна проблема с этим - когда копирую большой файл. Событие добавления запускается немедленно, а затем я получаю сотни событий изменения по мере выполнения копирования файла. Есть ли способ вызвать только одно событие при завершении копирования файла?
Curious101
5
@ Curious101, пробовали добавить awaitWriteFinish: true? По умолчанию это false.
cs_pupil
Я хочу спросить одну вещь, стоит ли использовать ее в большой файловой системе, вы можете сказать, что я хочу контролировать /home/terabyte. Ну не рекурсивно
tbhaxor
42

Почему бы просто не использовать старое fs.watch? Это довольно просто.

fs.watch('/path/to/folder', (eventType, filename) => {
console.log(eventType);
// could be either 'rename' or 'change'. new file event and delete
// also generally emit 'rename'
console.log(filename);
})

Для получения дополнительной информации и подробностей о параметрах параметров см. Документы Node fs.

Кошик Эвани
источник
7
Примечание к предупреждению, я тестировал это на своем Mac, и этот код определяет только этот уровень папки, а не какие-либо подкаталоги для изменений, поэтому обязательно добавьте параметр для рекурсивного просмотра в качестве второго параметра; см. документы по
ссылке
1
Добавлено примечание к примечанию @ OzzyTheGiant: рекурсивный вариант поддерживается только в macOS и Windows.
Кошик Эвань
Node fs.watch()немного неуклюж, и вам нужно создать свою победившую реализацию противодействия.
mwieczorek
@mwieczorek Что означает "противодействие"?
Thomas Jay Rush
2
@ThomasJayRush - механизм, позволяющий пройти определенное количество времени между событием и действием, поэтому, если событие срабатывает дважды, действие вызывается только один раз. Это технический термин, в котором физическая кнопка запускает электрический ток, но кнопка «подпрыгивает» один или несколько раз, создавая несколько всплесков тока там, где требуется только один, что также можно применить к программированию, особенно JS. medium.com/@jamischarles/what-is-debouncing-2505c0648ff1
mwieczorek
12

попробуй гончую :

hound = require('hound')

// Create a directory tree watcher.
watcher = hound.watch('/tmp')

// Create a file watcher.
watcher = hound.watch('/tmp/file.txt')

// Add callbacks for file and directory events.  The change event only applies
// to files.
watcher.on('create', function(file, stats) {
  console.log(file + ' was created')
})
watcher.on('change', function(file, stats) {
  console.log(file + ' was changed')
})
watcher.on('delete', function(file) {
  console.log(file + ' was deleted')
})

// Unwatch specific files or directories.
watcher.unwatch('/tmp/another_file')

// Unwatch all watched files and directories.
watcher.clear()

Он будет выполняться после изменения файла

Шарати РБ
источник