Observe los cambios en una carpeta con node.js e imprima las rutas de archivo cuando se modifiquen

87

Estoy tratando de escribir un script node.js que observe los cambios en un directorio de archivos y luego imprima los archivos que se modifican. ¿Cómo puedo modificar este script para que observe un directorio (en lugar de un archivo individual) e imprima los nombres de los archivos en el directorio a medida que se cambian?

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?
});
Anderson Green
fuente
Me pregunto si esto es relevante: stackoverflow.com/questions/12063266/… (aunque no estoy familiarizado con gruntjs, espero que haya otras soluciones).
Anderson Green
Quizás algo como node-inotify-plusplus sería útil: stackoverflow.com/questions/5877263/…
Anderson Green
¿Qué sistema operativo estás ejecutando? Esto es importante, ya que los mecanismos de bajo nivel para ver un archivo son muy diferentes según los usos de Unix / Linux inotify, los usos de OSX FSWatchy no tengo idea de Windoze, pero estoy seguro de que Google podría decírselo.
srquinn
1
Aunque originalmente usé el plano node-inotifyen mi proyecto, finalmente lo cambié node-inotify-plusplusporque ¿a quién no le gustan las abstracciones? =)
srquinn

Respuestas:

145

Prueba 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 resuelve algunos de los problemas de plataformas cruzadas con la visualización de archivos usando solo fs.

mtsr
fuente
3
¿Maneja subcarpetas?
Stepan Yakovenko
1
Un problema con esto: cuando copio un archivo grande. El evento de adición se activa inmediatamente y luego obtengo cientos de eventos de cambio a medida que avanza la copia del archivo. ¿Alguna forma de activar solo un evento para cuando finalice la copia del archivo?
Curious101
5
@ Curious101, ¿has intentado agregar awaitWriteFinish: true? Es falso por defecto.
cs_pupil
Quiero preguntar una cosa, si vale la pena usarlo en un sistema de archivos grande, puede decir que quiero monitorear /home/terabyte. Bueno, no recursivo
tbhaxor
42

¿Por qué no usar el viejo fs.watch? Es bastante sencillo.

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

Para obtener más información y detalles sobre el parámetro de opciones, consulte Node fs Docs

Kaushik Evani
fuente
7
Nota de advertencia, he probado esto en mi mac, y este código solo detecta ese nivel de carpeta y no ningún subdirectorio para cambios, así que asegúrese de agregar la opción para mirar de forma recursiva como segundo parámetro; ver los documentos vinculados arriba
OzzyTheGiant
1
Nota agregada a la nota de @ OzzyTheGiant: la opción recursiva solo es compatible con macOS y Windows.
Kaushik Evani
El nodo fs.watch()es un poco torpe, y tienes que construir tu implementación de rebote ganado.
mwieczorek
@mwieczorek ¿Qué significa "rebote"?
Thomas Jay Rush
2
@ThomasJayRush un mecanismo que permite que transcurra una cierta cantidad de tiempo entre un evento y la acción, de modo que si un evento se activa dos veces, la acción solo se invoca una vez. Es un término de ingeniería en el que un botón físico activaría corriente eléctrica, pero el botón "rebotaría" una o más veces, creando múltiples picos en la corriente donde solo se deseaba uno, que también se puede aplicar a la programación, especialmente JS. medium.com/@jamischarles/what-is-debouncing-2505c0648ff1
mwieczorek
12

prueba sabueso :

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

Se ejecutará una vez que se cambie el archivo

Sharathi RB
fuente