[英]Getting empty string from fs.readFile inside chokidar.watch(path_file).on('change', ...)
我有以下非常簡單的Node
項目:
https://github.com/tlg-265/chokidar-issue
$ git clone https://github.com/tlg-265/chokidar-issue
$ cd chokidar-issue
$ npm i
$ npm run watch-changes
它基本上負責檢測文件中的更改:
/profiles/bill-gates.json
然后做一個動作。
為了做到這一點,我有以下文件:
/profile-watcher.js
const fs = require('fs-extra');
const colors = require('colors/safe');
const chokidar = require('chokidar');
const path_file = `profiles/bill-gates.json`;
console.log(`Current Profile: ${colors.red.bgBrightYellow(path_file)}`);
let profile_before = {};
chokidar.watch(path_file).on('change', async (path) => {
console.log();
console.log(`${colors.blue.bgYellow(`->`)} Profile changed: ${path}`);
fs.readFile(path, (err, profile_json) => {
console.log(`->${profile_json}<-`);
let profile = JSON.parse(profile_json);
if (JSON.stringify(profile) != JSON.stringify(profile_before)) {
console.log('The profile has changed.');
profile_before = profile;
}
});
});
當我運行項目時:
$ npm run watch-changes
並對文件進行以下修改: /profiles/bill-gates.json
Bill Gates -> Bill Gates ABC
Bill Gates ABC -> Bill Gates ABC DEF
它工作正常,將此文件的內容輸出到控制台。
但是當我進行下一次修改時:
Bill Gates ABC -> Bill Gates ABC DEF GHI
然后我收到以下錯誤:
-> Profile changed: profiles\bill-gates.json
-><-
undefined:1
SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at fs.readFile (\chokidar-issue\profile-watcher.js:17:24)
at \chokidar-issue\node_modules\graceful-fs\graceful-fs.js:115:16
at FSReqWrap.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:53:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! chokidar-issue@1.0.0 watch-changes: `node profile-watcher.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the chokidar-issue@1.0.0 watch-changes script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Roaming\npm-cache\_logs\2020-02-28T23_44_01_038Z-debug.log
/profiles/bill-gates.json
(標志: UTF-8 / CRLF
)
{
"name": "Bill Gates",
"email": "bill.gates@microsoft.com",
"password": "windows",
"country": "USA"
}
順便說一句,如果我從CRLF
正常更改為LF
我可以在崩潰之前再做一些修改。
我的印象是,由於某些原因,文件: /profiles/bill-gates.json
在某個時候被鎖定,當Node
嘗試讀取它時,它會返回一個空字符串,因為它被鎖定了。
關於如何在幾次嘗試后不崩潰的情況下進行這項工作的任何想法?
謝謝!
我和你有同樣的問題。
“chokidar”中有一個選項,您可以在其中awaitWriteFinish
。 它是基於時間的,並檢查文件的大小是否發生變化。 如果沒有,那么它將調用回調。
const watcher = chokidar.watch(configPathString, {
persistent: true,
awaitWriteFinish: {
stabilityThreshold: 500
}
});
watcher.on('change', (path, stats) => {
fs.readFile(configPathString,(err, data)=>{
if (err) throw err;
//console.log('data',data);
let receivedData = JSON.parse(data);
//Do whatever you like
})
});
這可能是一個競爭條件。 像這樣使您的 JSON.parse 安全:
const path = require('path')
chokidar.watch(path_file).on('change', async (path) => {
fs.readFile(path, 'utf8', (err, profile_json) => {
if (!profile_json) {
console.log(`${path} is an empty file!`)
return
}
const profile = JSON.parse(profile_json);
if (JSON.stringify(profile) != JSON.stringify(profile_before)) {
console.log('The profile has changed.');
profile_before = profile;
}
});
});
我可以通過添加一些恢復回退來使其工作:
const fs = require('fs-extra');
const colors = require('colors/safe');
const chokidar = require('chokidar');
const sleep = require('sleep');
const path_file = `profiles/bill-gates.json`;
console.log(`Current Profile: ${colors.red.bgBrightYellow(path_file)}`);
let profile_before = fs.readFileSync(path_file).toString();
chokidar.watch(path_file).on('change', async (path_changed) => {
let profile = fs.readFileSync(path_changed).toString();
if (IsValidJson(profile)) {
if (profile != profile_before) {
console.log();
console.log(`Profile changed: ${colors.red.bgBrightYellow(path_changed)}`);
process_profile(profile);
profile_before = profile;
}
}
else {
sleep.msleep(100); // this is necessary
}
});
function process_profile(profile_json) {
const profile = JSON.parse(profile_json);
console.log(`${profile_json}`);
console.log(profile.name);
}
function IsValidJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
似乎當您保存文件時(至少在 Windows 上),有時在文件變清晰和幾毫秒后它會獲得實際內容之間(非常非常短的時間)有一段時間。 在這兩種情況下, on-change
事件都會被觸發。 所以,我們只需要驗證文件的內容是否是JSON。 在這種情況下,我只需要忽略它並等待下一個on-change
事件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.