Obserwuj folder pod kątem zmian przy użyciu node.js i drukuj ścieżki plików, gdy zostaną zmienione


93

Próbuję napisać skrypt node.js, który obserwuje zmiany w katalogu plików, a następnie drukuje pliki, które zostały zmienione. Jak mogę zmodyfikować ten skrypt, aby obserwował katalog (zamiast pojedynczego pliku) i wyświetlał nazwy plików w katalogu w miarę ich zmiany?

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?
});

Zastanawiam się, czy to ma znaczenie: stackoverflow.com/questions/12063266/… (chociaż nie znam gruntjs - mam nadzieję, że są inne rozwiązania).
— Anderson Green

Może przydałoby się coś takiego jak node-inotify-plusplus: stackoverflow.com/questions/5877263/…
— Anderson Green

Z jakiego systemu operacyjnego korzystasz? Ma to znaczenie, ponieważ mechanizmy niskiego poziomu do oglądania pliku są bardzo różne, ponieważ używa Unix / Linux inotify, OSX FSWatchi nie mam pojęcia o Windoze, ale jestem pewien, że Google może ci powiedzieć.
— srquinn

1
Chociaż pierwotnie użyłem prostoty node-inotifyw moim projekcie, w końcu przeszedłem na, node-inotify-plusplusponieważ kto nie lubi abstrakcji? =)
— srquinn

Odpowiedzi:


149

Wypróbuj Chokidar :

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 rozwiązuje niektóre problemy międzyplatformowe związane z oglądaniem plików przy użyciu samego fs.


3
Czy obsługuje podfoldery?
— Stepan Yakovenko

1
Jeden problem z tym - kiedy kopiuję duży plik. Zdarzenie dodawania jest wyzwalane natychmiast, a następnie otrzymuję setki zdarzeń zmian w miarę postępu kopiowania pliku. Czy jest jakiś sposób, aby wywołać tylko jedno zdarzenie po zakończeniu kopiowania pliku?
— Ciekawy 101

5
@ Curious101, czy próbowałeś dodać awaitWriteFinish: true? Domyślnie jest fałszywe.
— cs_pupil,

Chcę zapytać o jedno, czy warto go używać na dużym systemie plików, możesz powiedzieć, że chcę monitorować /home/terabyte. Cóż, nie rekurencyjne
— tbhaxor

45

Dlaczego po prostu nie użyć starego fs.watch? To całkiem proste.

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);
})

Aby uzyskać więcej informacji i szczegółów na temat parametrów opcji, zobacz dokumentację Node fs


8
Uwaga ostrzegawcza: przetestowałem to na moim komputerze Mac i ten kod wykrywa tylko ten poziom folderu, a nie żadne podkatalogi dla zmian, więc upewnij się, że jako drugi parametr dodano opcję oglądania rekurencyjnego; zobacz dokumenty, do których linki znajdują się powyżej
— OzzyTheGiant

1
Dodano uwagę do notatki @ OzzyTheGiant: Opcja rekurencyjna jest obsługiwana tylko w systemach macOS i Windows.
— Kaushik Evani

Węzeł fs.watch()jest trochę niezgrabny i musisz zbudować swoją wygraną implementację debounce.
— mwieczorek

3
@ThomasJayRush mechanizm, który pozwala na upływ czasu między zdarzeniem a akcją, więc jeśli zdarzenie zostanie uruchomione dwukrotnie, akcja zostanie wywołana tylko raz. Jest to termin inżynieryjny, w którym fizyczny przycisk wyzwalałby prąd elektryczny, ale przycisk „odbijałby się” raz lub więcej razy, tworząc wiele skoków w prądzie tam, gdzie tylko jeden był pożądany - co można zastosować również do programowania - zwłaszcza JS. medium.com/@jamischarles/what-is-debouncing-2505c0648ff1
— mwieczorek

1
użyj chokidar, ponieważ ten interfejs API nie jest spójny na różnych platformach.
— Sandeep Gahlawat

12

spróbuj ogar :

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

Uruchomi się po zmianie pliku

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.