
2018-5-21 19:06:48|circuit board 2018-5-21 10:11:22|dash button 2018-5-20 11:46:54|web $ npm init -y package.json file for the Node.js project.package.json as a dependency: $ npm install --save log-timestamp log-timestamp package allows you to attach a time stamp to messages that are output to the console using the console.log command. This will allow you to analyze the time of occurrence of events related to the monitoring of files. This package is needed solely for training purposes, and, for example, if you will be preparing something similar to what we are going to talk about, for use in production, you will not need to log-timestamp .fs.watchFile . const fs = require('fs'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); fs.watchFile(buttonPressesLogFile, (curr, prev) => { console.log(`${buttonPressesLogFile} file Changed`); }); button-pressed.log . Callback is called after the file is changed.fs.stats type. This is an object with data about the current state of the file ( curr ), and an object with data about its previous state ( prev ). This allows, for example, to find out the time of the previous file modification using the prev.mtime construct.button-pressed.log and make changes to it, the program will respond to this, the corresponding entry will appear in the console. $ node file-watcher.js [2018-05-21T00:54:55.885Z] Watching for file changes on ./button-presses.log [2018-05-21T00:55:04.731Z] ./button-presses.log file Changed fs.watchFile method, by default, polls files for changes every 5.007 seconds. This time can be changed by passing fs.watchFile object with parameters containing the interval property to the fs.watchFile method: fs.watchFile(buttonPressesLogFile, { interval: 1000 }, (curr, prev) => { console.log(`${buttonPressesLogFile} file Changed`); }); fs.watchFile spends system resources on polling files, fs.watch relies on the operating system for system notifications of file system changes. The documentation says that Node uses the inotify mechanism in the Linux OS, FSEvents on MacOS, and ReadDirectoryChangesW on Windows to receive asynchronous notifications when files change (compare this with synchronous polling of files). The performance gain derived from using fs.watch instead of fs.watchFile is even more significant when, for example, you need to keep track of all files in a certain directory, since you can pass either the path to the specific file as the first argument to fs.watch file or folder. fs.watch . const fs = require('fs'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); fs.watch(buttonPressesLogFile, (event, filename) => { if (filename) { console.log(`${filename} file Changed`); } }); $ node file-watcher.js [2018-05-21T00:55:52.588Z] Watching for file changes on ./button-presses.log [2018-05-21T00:56:00.773Z] button-presses.log file Changed [2018-05-21T00:56:00.793Z] button-presses.log file Changed [2018-05-21T00:56:00.802Z] button-presses.log file Changed [2018-05-21T00:56:00.813Z] button-presses.log file Changed fs.watch . This method allows you to respond to events that occur either when a file is renamed (these are rename events) or when its content changes. If we need accuracy and we only want to observe changes in the contents of the file, the code should be brought to the following state: const fs = require('fs'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); fs.watch(buttonPressesLogFile, (event, filename) => { if (filename && event ==='change') { console.log(`${filename} file Changed`); } }); rename event could be detected when running Node under Windows, but not under Raspbian.fs.watch code by observing the moment of file modification, which will allow us to identify real changes and avoid false positives of the handler. const fs = require('fs'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); let previousMTime = new Date(0); fs.watch(buttonPressesLogFile, (event, filename) => { if (filename) { const stats = fs.statSync(filename); if (stats.mtime.valueOf() === previousMTime.valueOf()) { return; } previousMTime = stats.mtime; console.log(`${filename} file Changed`); } }); previousMTime variable the value of the previous file modification moment and call console.log only in cases when the file modification time changes. It seems that this idea is good and now everything should work as we need. Check it out. $ node file-watcher.js [2018-05-21T00:56:50.167Z] Watching for file changes on ./button-presses.log [2018-05-21T00:56:55.611Z] button-presses.log file Changed [2018-05-21T00:56:55.629Z] button-presses.log file Changed [2018-05-21T00:56:55.645Z] button-presses.log file Changed fs.watch responds fs.watch , we calculate the checksum again. We may be able to get rid of unnecessary messages about changing the file, if we take into account the state of the contents of the file. $ npm install --save md5 const fs = require('fs'); const md5 = require('md5'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); let md5Previous = null; fs.watch(buttonPressesLogFile, (event, filename) => { if (filename) { const md5Current = md5(fs.readFileSync(buttonPressesLogFile)); if (md5Current === md5Previous) { return; } md5Previous = md5Current; console.log(`${filename} file Changed`); } }); $ node file-watcher.js [2018-05-21T00:56:50.167Z] Watching for file changes on ./button-presses.log [2018-05-21T00:59:00.924Z] button-presses.log file Changed [2018-05-21T00:59:00.936Z] button-presses.log file Changed fs.watch , but never achieved what we wanted. However, not everything is so bad, because, in the search for a solution, we learned a lot of useful information. Let's make another attempt to achieve the desired. At this time, we use the technology to eliminate the “chatter” of events by entering into our code a small delay, which will allow us not to react to events about file changes within the specified time window. const fs = require('fs'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); let fsWait = false; fs.watch(buttonPressesLogFile, (event, filename) => { if (filename) { if (fsWait) return; fsWait = setTimeout(() => { fsWait = false; }, 100); console.log(`${filename} file Changed`); } }); $ node file-watcher.js [2018-05-21T00:56:50.167Z] Watching for file changes on ./button-presses.log [2018-05-21T01:00:22.904Z] button-presses.log file Changed const fs = require('fs'); const md5 = require('md5'); require('log-timestamp'); const buttonPressesLogFile = './button-presses.log'; console.log(`Watching for file changes on ${buttonPressesLogFile}`); let md5Previous = null; let fsWait = false; fs.watch(buttonPressesLogFile, (event, filename) => { if (filename) { if (fsWait) return; fsWait = setTimeout(() => { fsWait = false; }, 100); const md5Current = md5(fs.readFileSync(buttonPressesLogFile)); if (md5Current === md5Previous) { return; } md5Previous = md5Current; console.log(`${filename} file Changed`); } }); fs.watchFile to monitor files fs.watchFile not recommended, since this command, in order to detect file change events, performs regular queries to the system. Instead, pay attention to fs.watch with a function to suppress the "bounce" of events.Source: https://habr.com/ru/post/360495/
All Articles