Observe as alterações em uma pasta usando o node.js e imprima os caminhos dos arquivos quando eles forem alterados


87

Estou tentando escrever um script node.js que observa as alterações em um diretório de arquivos e, em seguida, imprime os arquivos que foram alterados. Como posso modificar este script para que observe um diretório (em vez de um arquivo individual) e imprima os nomes dos arquivos no diretório à medida que são alterados?

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

Eu me pergunto se isso é relevante: stackoverflow.com/questions/12063266/… (Não estou familiarizado com gruntjs, embora - espero que haja outras soluções.)
Anderson Green

Talvez algo como node-inotify-plusplus seja útil: stackoverflow.com/questions/5877263/…
Anderson Green

Qual sistema operacional você está usando? Isso é importante porque os mecanismos de baixo nível para assistir a um arquivo são muito diferentes conforme o Unix / Linux usa inotify, o OSX usa FSWatche eu não tenho ideia sobre o Windoze, mas tenho certeza que o Google poderia te dizer.
srquinn

1
Embora eu tenha usado originalmente o plano node-inotifyem meu projeto, acabei mudando para node-inotify-plusplusporque quem não gosta de abstrações? =)
srquinn

Respostas:


145

Experimente 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 resolve alguns dos problemas de plataforma cruzada ao assistir arquivos usando apenas fs.


3
Ele lida com subpastas?
Stepan Yakovenko de

1
Um problema com isso - quando copio um arquivo grande. O evento add é acionado imediatamente e eu obtenho centenas de eventos de alteração conforme o progresso da cópia do arquivo. Existe alguma forma de acionar apenas um evento para quando a cópia do arquivo terminar?
Curious101

5
@ Curious101, você já tentou adicionar awaitWriteFinish: true? É falso por padrão.
cs_pupil

Eu quero perguntar uma coisa, vale a pena usar em um sistema de arquivos grande, você pode dizer que quero monitorar /home/terabyte. Bem, não recursivo
tbhaxor

42

Por que não usar apenas o antigo fs.watch? É muito simples.

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 obter mais informações e detalhes sobre os parâmetros de opções, consulte Node fs Docs


7
Nota de advertência, eu testei isso no meu mac, e este código detecta apenas aquele nível de pasta e não quaisquer subdiretórios para alterações, então certifique-se de adicionar a opção de assistir recursivamente como o segundo parâmetro; veja os documentos relacionados acima
OzzyTheGiant

1
Nota adicionada à nota de @OzzyTheGiant: a opção recursiva só é compatível com macOS e Windows.
Kaushik Evani

O do Node fs.watch()é um pouco desajeitado e você precisa construir sua implementação de debounce ganha.
mwieczorek de

@mwieczorek O que significa 'debounce'?
Thomas Jay Rush

2
@ThomasJayRush um mecanismo que permite que um determinado período de tempo passe entre um evento e a ação ocorra; portanto, se um evento for disparado duas vezes, a ação será chamada apenas uma vez. É um termo de engenharia em que um botão físico acionaria corrente elétrica, mas o botão "saltaria" uma ou mais vezes, criando vários picos na corrente onde apenas um era desejado - o que também pode ser aplicado à programação - especialmente JS. medium.com/@jamischarles/what-is-debouncing-2505c0648ff1
mwieczorek

12

tente hound :

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

Será executado assim que o arquivo for alterado

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.