Подтвердить что ты не робот

Fs.watch дважды выстрелил, когда я меняю просматриваемый файл

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

ВЫВОД:

  • некоторые данные
  • Готово X 1
  • некоторые данные
  • Готово X 2

Это моя ошибка использования или...?

4b9b3361

Ответ 2

Я учитываю это, выполняя следующие действия:

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

Ответ 3

Я предлагаю работать с chokidar (https://github.com/paulmillr/chokidar), который намного лучше, чем fs.watch:

Комментарий к README.md:

Node.js fs.watch:

  • Не сообщает имена файлов в OS X.
  • Не сообщается о событиях вообще при использовании таких редакторов, как Sublime на OS X.
  • Часто сообщает о событиях дважды.
  • Исправляет большинство изменений как rename.
  • Имеет множество других проблем
  • Не предоставляет простой способ рекурсивного просмотра файлов деревьев.

Node.js fs.watchFile:

  • Почти так же плохо при обработке событий.
  • Также не обеспечивает рекурсивного просмотра.
  • Результаты высокой загрузки процессора.

Ответ 4

Если вам нужно посмотреть файл на предмет изменений, вы можете проверить мою небольшую библиотеку on-file-change. Он проверяет хэш файла sha1 между запущенными событиями change.

Объяснение того, почему мы имеем несколько запущенных событий:

В некоторых случаях вы можете заметить, что одно событие создания генерирует несколько созданных событий, которые обрабатываются вашим компонентом. Например, если вы используете компонент FileSystemWatcher для отслеживания создания новых файлов в каталоге, а затем протестируйте его, используя Notepad для создания файла, вы можете увидеть два созданных события, даже если был создан только один файл. Это связано с тем, что в процессе записи Notepad выполняет несколько действий файловой системы. Блокнот записывает на диск партиями, которые создают содержимое файла, а затем атрибуты файла. Другие приложения могут работать одинаково. Поскольку FileSystemWatcher контролирует действия операционной системы, все события, которые срабатывают эти приложения, будут подняты.

Источник

Ответ 5

сначала это изменение, а второе - переименование

мы можем отличить функцию слушателя

function(event, filename) {

}

Обратный вызов прослушивателя получает два аргумента (событие, имя файла). событие - либо "переименовать", либо "изменить", а имя файла - это имя файла, вызвавшего событие.

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

в качестве исходного файла переименовывается в качестве целевого файла, он будет вызывать три события как факт

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

обратите внимание, что если вы хотите поймать все эти три evnet, посмотрите каталог исходного файла

Ответ 6

Я имею дело с этой проблемой в первый раз, поэтому все ответы до сих пор, вероятно, лучше моего решения, однако ни один из них не был на 100% подходящим для моего случая, поэтому я придумал что-то немного другое - я использовал операцию XOR для перевода целого числа от 0 до 1, эффективно отслеживая и игнорируя каждое второе событие в файле:

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

Я не хотел использовать функцию, связанную с временем (например, jwymanm answer), потому что файл, который я просматриваю, может гипотетически получать законные обновления очень часто. И я не хотел использовать список просмотренных файлов, таких как Erik P, потому что я смотрю только один файл. Решение Яна Święcki показалось излишним, поскольку я работаю над чрезвычайно короткими и простыми файлами в среде с низким энергопотреблением. Наконец, ответ Бернадо заставил меня немного нервничать - он проигнорировал бы второе обновление, только если он прибыл, прежде чем я закончил обработку первого, и я не могу справиться с такой неопределенностью. Если кто-то окажется в этом конкретном сценарии, может быть какая-то заслуга в подходе, который я использовал? Если что-нибудь в этом роде не так, пожалуйста, дайте мне знать/отредактировать этот ответ, но пока это работает хорошо?

ПРИМЕЧАНИЕ. Очевидно, это сильно предполагает, что вы получите ровно 2 события за реальные изменения. Очевидно, я тщательно проверил это предположение и узнал его ограничения. До сих пор я подтверждал, что:

  • Изменение файла в редакторе Atom и сохранение триггеров 2 обновления
  • touch триггеры 2 обновления
  • Перенаправление вывода через > (переписывание содержимого файла) триггеры 2 обновления
  • Добавление через >> иногда запускает 1 обновление! *

Я могу придумать совершенно веские причины для разных поведений, но нам не нужно знать, почему что-то происходит для планирования - я просто хотел подчеркнуть, что вы захотите проверить себя в своей собственной среде и в контексте ваших собственных случаев использования (duh) и не доверять самопознанным идиотом в Интернете. Сказанное, с принятыми предосторожностями, у меня пока не было странности.

* Полное раскрытие информации, я действительно не знаю, почему это происходит, но мы уже имеем дело с непредсказуемым поведением с функцией watch(), так что еще немного неопределенности? Для тех, кто следует за домом, более быстрое добавление к файлу, похоже, заставляет его прекратить двойное обновление, но, честно говоря, я действительно не знаю, и мне нравится поведение этого решения в том случае, если оно будет, который является однострочным файлом, который будет обновляться (содержимое заменяется), как и два раза в секунду.

Ответ 7

Я иногда получаю многократные регистрации события Watch, вызывающие событие Watch в несколько раз. Я решил это, сохранив список наблюдаемых файлов и не регистрируя событие, если файл allready находится в списке:

 var watchfiles = {};

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

......

Ответ 8

Аналогичная проблема. Мне нужно было сделать некоторые вещи с изображениями, когда они были добавлены в каталог. Здесь, как я имел дело с двойным стрельбой:

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

Он проигнорирует вторую стрельбу, пока не закончит то, что он должен делать с новым файлом.

Ответ 9

Как и другие ответы, говорит... У этого много проблем, но я могу справиться с этим следующим образом:

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

Надеюсь, что смогу помочь тебе...

Ответ 10

Самое простое решение:

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 () {
  // ...
})

Ответ 11

Мое пользовательское решение

Мне лично нравится использовать return, чтобы предотвратить запуск кода кода при проверке чего-либо, так что вот мой метод:

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

Не стесняйтесь использовать этот пример для упрощения кода. Он может НЕ быть лучше, чем использовать модуль у других, но он работает очень хорошо!