Detecte alterações de arquivo em node.js via watchFile
-
25-09-2019 - |
Pergunta
Quero detectar alterações em um arquivo, se o arquivo mudar, usarei child_process para executar um comando scp para copiar o arquivo para um servidor. Pesquisei a documentação do node.js, a função fs.watchFile parece fazer o que eu quero faço, mas quando tentei, de alguma forma simplesmente não funcionou como eu esperava.O seguinte código foi usado:
var fs = require('fs');
console.log("Watching .bash_profile");
fs.watchFile('/home/test/.bash_profile', function(curr,prev) {
console.log("current mtime: " +curr.mtime);
console.log("previous mtime: "+prev.mtime);
if (curr.mtime == prev.mtime) {
console.log("mtime equal");
} else {
console.log("mtime not equal");
}
});
Com o código acima, se eu acessar o arquivo monitorado, a função de retorno de chamada será executada, gerará o mesmo mtime e sempre gerará "mtime diferente" (só estou acessando o arquivo).Saídas:
Watching .bash_profile
current mtime: Mon Sep 27 2010 18:41:27 GMT+0100 (BST)
previous mtime: Mon Sep 27 2010 18:41:27 GMT+0100 (BST)
mtime not equal
Alguém sabe por que a instrução if falhou (também tentei usar === verificação de identificação, mas ainda obteve a mesma saída) quando os dois mtime são iguais?
Solução
Se mtime
propriedades são Date
objetos, então estes nunca poderão ser iguais.Em JavaScript, dois objetos separados são iguais SOMENTE se forem realmente o mesmo objeto (as variáveis apontam para a mesma instância de memória)
obj1 = new Date(2010,09,27);
obj2 = new Date(2010,09,27);
obj3 = obj1; // Objects are passed BY REFERENCE!
obj1 != obj2; // true, different object instances
obj1 == obj3; // true, two variable pointers are set for the same object
obj2 != obj3; // true, different object instances
Para verificar se esses dois valores de data são iguais, use
curr.mtime.getTime() == prev.mtime.getTime();
(Na verdade, não tenho certeza se esse é o caso, pois não verifiquei se watchFile
gera objetos Date ou strings, mas definitivamente parece assim pela sua descrição)
Outras dicas
Para pessoas "inteligentes":
if (curr.mtime - prev.mtime) {
// file changed
}
Infelizmente a maneira correta é
if (+curr.mtime === +prev.mtime) {}
O + força o objeto de data a int que é unixtime.
Para simplificar as coisas que você pode usar Watchr Para obter eventos úteis (apenas disparará o change
Evento se um arquivo foi realmente alterado). Ele também suporta assistir a árvores de diretório inteiras :)
Usamos Chokidar para assistir a arquivos, que funciona mesmo no contexto duvidoso de uma máquina do CentOS em execução com um sistema de arquivos Windows (Vagrant VirtualBox Centos em execução no Windows Machine)
solução rápida e desagradável. Se você não estiver fazendo uma comparação de data em termos de anteriores ou depois (<ou>) e está simplesmente comparando os Datestrings, basta fazer um totetring rápido () em cada um.
if (curr.mtime.toString() == prev.mtime.toString())