Определить mtime-разрешение файловой системы - PullRequest
2 голосов
/ 23 ноября 2011

Как узнать, какое разрешение системы mtime у Node.js?

Почему я спрашиваю

В Node.js fs.watch иногда будет выдавать дубликатыchange событий.Чтобы избежать выполнения лишних действий, обычно используется такой код (из утилиты CoffeeScript coffee):

  if event is 'change'
    fs.stat source, (err, stats) ->
      throw err if err
      return if stats.size is prevStats.size and
        stats.mtime.getTime() is prevStats.mtime.getTime()
      prevStats = stats
      ...

Вот проблема: В OS X из-за базовой файловой системы HFS +, mtime имеет разрешение всего 1 секунду.То есть значения mtime.getTime() имеют вид

1322068921000

Таким образом, всякий раз, когда два изменения происходят в течение 1 секунды друг от друга, есть вероятность, что второе изменение не повлияет на mtime файла.Благодаря проверке stats.size эта проблема возникает только в том случае, если второе изменение не повлияло на размер файла.Тем не менее, это проблема.

Надежным решением было бы «отменить» события change к интервалу mtime;то есть в OS X, когда возникает change, я бы подождал 1 секунду, чтобы воздействовать на него (тем самым сгруппировав все события изменения, которые могут иметь один и тот же mtime вместе).Но я бы хотел отложить событие на минимально возможное время для каждой файловой системы, вместо того, чтобы использовать наибольший общий знаменатель.

Ответы [ 2 ]

1 голос
/ 19 июня 2014

У меня была идентичная проблема при написании кода Java.Эта проблема выходит за рамки Node.js, поскольку большинство языков имеют схожий API при работе с файлами (и все они ограничены специфическими ограничениями файловой системы).Другие файловые системы в Linux имеют такую ​​же проблему (гранулярность отметки времени 1 с), как и старый FAT32 для Windows.

Одно из хакерских решений - фактически установить mtime файла обратно за одну секунду до того, как вы прочитаете файл (или отправите его).файл событий).Таким образом, если другая модификация происходит в том же окне гранулярности (в данном случае 1), новый mtime будет другим, и вы сможете обнаружить модификацию.

Это должно работать хорошо, если нет другихприложения используют файл mtime, иначе он может очень сильно помешать их работе.Это обходной путь, на самом деле, не правильное решение.Тем не менее, я нашел это полезным в некоторых сценариях, например, для автоматизированных тестов моего Java-кода (тесты изменяют файлы в быстрой последовательности, больше, чем это обычно происходит при использовании в реальном мире).

1 голос
/ 23 ноября 2011

Переберите все файлы в каком-либо каталоге (например, / tmp) и сделайте что-то вроде этого

files.forEach(function(filename) {
    sum += fs.statSync(filename).mtime % 1000;
});

if (sum == 0) {
   // supports only 1 second resolution
} 

Немного хак, я знаю.

...