sistemas sistema propósito mac los especial ejemplos caracteristicas archivos node.js windows-8 watch

node.js - propósito - sistemas de archivos de windows



fs.watch disparó dos veces cuando cambio el archivo visto (11)

fs.watch( ''example.xml'', function ( curr, prev ) { // on file change we can read the new xml fs.readFile( ''example.xml'',''utf8'', function ( err, data ) { if ( err ) throw err; console.dir(data); console.log(''Done''); }); });

SALIDA:

  • algunos datos
  • Hecho X 1
  • algunos datos
  • Hecho X 2

¿Es mi culpa de uso o ...?


Mi solución personalizada

Personalmente, me gusta usar return para evitar que se ejecute un bloque de código al verificar algo, así que aquí está mi método:

var watching = false; fs.watch(''./file.txt'', () => { if(!watching) return; watching = true; // do something // the timeout is to prevent the script to run twice with short functions // the delay can be longer to disable the function for a set time setTimeout(() => { watching = false; }, 100); };

Siéntase libre de usar este ejemplo para simplificar su código. Puede que NO sea ​​mejor que usar un módulo de otros, ¡pero funciona bastante bien!


Al igual que otras respuestas, dice ... Esto tiene muchos problemas, pero puedo lidiar con esto de esta manera:

var folder = "/folder/path/"; var active = true; // flag control fs.watch(folder, function (event, filename) { if(event === ''rename'' && active) { //you can remove this "check" event active = false; // ... its just an example for (var i = 0; i < 100; i++) { console.log(i); } // ... other stuffs and delete the file if(!active){ try { fs.unlinkSync(folder + filename); } catch(err) { console.log(err); } active = true } } });

Espero poder ayudarte ...


Algunas veces obtengo múltiples registros del evento Watch, lo que provoca que el evento Watch se dispare varias veces. Lo resolví manteniendo una lista de archivos de visualización y evito registrar el evento si el archivo ya está en la lista:

var watchfiles = {}; function initwatch(fn, callback) { if watchlist[fn] { watchlist[fn] = true; fs.watch(fn).on(''change'', callback); } }

......


Estoy lidiando con este problema por primera vez, por lo que todas las respuestas hasta ahora son probablemente mejores que mi solución, sin embargo, ninguna de ellas fue 100% adecuada para mi caso, así que se me ocurrió algo ligeramente diferente: usé un XOR operación para voltear un número entero entre 0 y 1, manteniendo un seguimiento efectivo e ignorando cada segundo evento en el archivo:

var targetFile = "./watchThis.txt"; var flippyBit = 0; fs.watch(targetFile, {persistent: true}, function(event, filename) { if (event == ''change''){ if (!flippyBit) { var data = fs.readFile(targetFile, "utf8", function(error, data) { gotUpdate(data); }) } else { console.log("Doing nothing thanks to flippybit."); } flipBit(); // call flipBit() function } }); // Whatever we want to do when we see a change function gotUpdate(data) { console.log("Got some fresh data:"); console.log(data); } // Toggling this gives us the "every second update" functionality function flipBit() { flippyBit = flippyBit ^ 1; }

No quería usar una función relacionada con el tiempo (como la respuesta de jwymanm) porque el archivo que estoy viendo podría hipotéticamente obtener actualizaciones legítimas con mucha frecuencia. Y no quería usar una lista de archivos vistos como sugiere Erik P, porque solo estoy viendo un archivo. La solución de Jan Święcki parecía una exageración, ya que estoy trabajando en archivos extremadamente cortos y simples en un entorno de bajo consumo. Por último, la respuesta de Bernado me puso un poco nerviosa: solo ignoraría la segunda actualización si llegaba antes de que terminara de procesar la primera, y no puedo manejar ese tipo de incertidumbre. Si alguien se encontrara en este escenario tan específico, ¿podría haber algún mérito en el enfoque que utilicé? Si hay algún error masivo con eso, hágamelo saber / editar esta respuesta, pero hasta ahora parece funcionar bien.

NOTA: Obviamente, esto supone que obtendrás exactamente 2 eventos por cambio real. Probé cuidadosamente esta suposición, obviamente, y aprendí sus limitaciones. Hasta ahora he confirmado que:

  • Modificando un archivo en el editor Atom y guardando los disparadores 2 actualizaciones
  • touch dispara 2 actualizaciones
  • La redirección de salida a través de > (sobrescribiendo el contenido del archivo) desencadena 2 actualizaciones
  • Añadir a través de >> veces desencadena 1 actualización! *

Puedo pensar en razones perfectamente buenas para los diferentes comportamientos, pero no necesitamos saber por qué algo está sucediendo para planificarlo. Sólo quería subrayar que querrá comprobarlo en su propio entorno y en el contexto. de sus propios casos de uso (duh) y no confíe en un idiota confeso en Internet. Dicho esto, con las precauciones tomadas, no he tenido ninguna rareza hasta ahora.

* Revelación completa, no sé realmente por qué sucede esto, pero ya estamos lidiando con un comportamiento impredecible con la función watch (), así que, ¿qué hay un poco más de incertidumbre? Para cualquier persona que lo siga en casa, los apéndices más rápidos a un archivo parecen hacer que se detenga la actualización doble pero, honestamente, no lo sé, y estoy cómodo con el comportamiento de esta solución en el caso real. Se utilizará, que es un archivo de una línea que se actualizará (contenido reemplazado) como dos veces por segundo de la manera más rápida.


La api de fs.watch :

  1. es unstable
  2. Ha conocido "comportamiento" con respecto a las notificaciones repetidas. Específicamente, el caso de Windows es un resultado del diseño de Windows, donde una modificación de un solo archivo puede ser múltiples llamadas a la API de Windows

La solución más fácil:

const watch = (path, opt, fn) => { var lock = false fs.watch(path, opt, function () { if (!lock) { lock = true fn() setTimeout(() => lock = false, 1000) } }) } watch(''/path'', { interval: 500 }, function () { // ... })


Lo primero es cambio y lo segundo es renombrar.

Podemos hacer una diferencia con la función de oyente.

function(event, filename) { }

La devolución de llamada del oyente obtiene dos argumentos (evento, nombre de archivo). evento es ''cambiar de nombre'' o ''cambiar'', y nombre de archivo es el nombre del archivo que activó el evento.

// rm sourcefile targetfile fs.watch( sourcefile_dir , function(event, targetfile)){ console.log( targetfile, ''is'', event) }

como un archivo de origen se renombra como archivo de destino, llamará a tres eventos como un hecho

null is rename // sourcefile not exist again targetfile is rename targetfile is change

Observe que, si desea capturar estos tres evnet, vea el directorio de sourcefile.


Me permito hacer esto haciendo lo siguiente:

var fsTimeout fs.watch(''file.js'', function(e) { if (!fsTimeout) { console.log(''file.js %s event'', e) fsTimeout = setTimeout(function() { fsTimeout=null }, 5000) // give 5 seconds for multiple events } }


Si necesita ver su archivo en busca de cambios, entonces puede revisar mi pequeña biblioteca on-file-change . Comprueba el hash de sha1 del archivo entre eventos de change disparados.

Explicación de por qué tenemos múltiples eventos disparados:

En ciertas situaciones, puede observar que un solo evento de creación genera múltiples eventos creados que son manejados por su componente. Por ejemplo, si usa un componente FileSystemWatcher para monitorear la creación de nuevos archivos en un directorio y luego lo prueba usando el Bloc de notas para crear un archivo, puede ver dos eventos creados generados aunque solo se haya creado un único archivo. Esto se debe a que el Bloc de notas realiza varias acciones del sistema de archivos durante el proceso de escritura. El Bloc de notas escribe en el disco en lotes que crean el contenido del archivo y luego los atributos del archivo. Otras aplicaciones pueden realizar de la misma manera. Debido a que FileSystemWatcher supervisa las actividades del sistema operativo, todos los eventos que estas aplicaciones activan serán recogidos.

Source


Similar / mismo problema. Necesitaba hacer algunas cosas con imágenes cuando se agregaron a un directorio. Así es como me ocupé de la doble cocción:

var fs = require(''fs''); var working = false; fs.watch(''directory'', function (event, filename) { if (filename && event == ''change'' && active == false) { active = true; //do stuff to the new file added active = false; });

Ignorará el segundo disparo hasta que termine lo que tiene que hacer con el nuevo archivo.


Sugiero trabajar con chokidar ( https://github.com/paulmillr/chokidar ) que es mucho mejor que fs.watch :

Comentando su README.md:

Node.js fs.watch :

  • No informa los nombres de archivo en OS X.
  • No informa eventos en absoluto cuando se usan editores como Sublime en OS X.
  • A menudo informa eventos dos veces.
  • Emite la mayoría de los cambios como rename .
  • Tiene muchos otros problemas
  • No proporciona una forma fácil de ver recursivamente los árboles de archivos.

Node.js fs.watchFile :

  • Casi tan malo en el manejo de eventos.
  • Además, no proporciona ninguna observación recursiva.
  • Resultados en alta utilización de la CPU.