使用 fs 读取文件后解析 Json

Posted

技术标签:

【中文标题】使用 fs 读取文件后解析 Json【英文标题】:Parsing Json after reading file with fs 【发布时间】:2016-11-27 12:55:54 【问题描述】:

我正在尝试在两个 node.js 脚本之间建立通信。 第一个执行获取请求并将响应写入文件。 第二个看修改后的文件,然后读取,提示结果。

第一个(get then write)

var request = require('request');
var parseString = require('xml2js').parseString;
var fs = require('fs');

//Some needed variables

streamInterval = setInterval(function() 
      request.get(addr, function (error, response, body) 
      if (!error && response.statusCode == 200) 
        parseString(body, explicitArray : false, ignoreAttrs : true , function (err, result) 
            var jsonResult = JSON.stringify(result);
            var result = JSON.parse(jsonResult);

            fs.writeFile(outputDeparts, JSON.stringify(result, null, 4), function(err) 
                if(err) 
                  console.log(err);
                
            ); 

        );
      else
        console.log("An error occured : " + response.statusCode);
      
    ).auth(LOGIN,PASS,true);
  , 30000);

第二个(注意变化,阅读并提示)

var fs = require('fs');

//Some needed variables


fs.watch(outputDeparts, (eventType, filename) => 
  console.log(`event type is: $eventType`);
  if (filename) 
    console.log(`filename provided: $filename`);
    fs.readFile(outputDeparts, 'utf8', function (err, data) 
      if (err)
        throw err;
      else
        console.log('start parsing');
        console.log(data);
        var result = JSON.parse(data);
        var departs = result["passages"]["train"];
        console.log(`next train [$departs[0]["num"]] at : $departs[0]["date"]`);
      
    );
   else 
    console.log('filename not provided');
  
);

第一次更改文件时一切正常!但是 30 秒后,在第二次更改时,我收到以下错误:

undefined:1

SyntaxError: Unexpected end of input
    at Object.parse (native)
    at /Users/adobe/Documents/workspace/playWithNode/watchFile.js:17:23
    at tryToString (fs.js:414:3)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:401:12)

我认为这是异步读取/写入文件的问题,但没有设法找到解决方法... 每个人都可以帮助我或有线索吗?谢谢

【问题讨论】:

【参考方案1】:

..不鼓励异步访问文件系统,因为在访问时,目标文件可以被应用生命周期中的某些东西修改。

我建议您使用 fs.readFileSync 并将 JSON.parse 包装在 try-catch 中

var fs = require('fs');

function onNextTrain(data)  
  console.log("onNextTrain", data);
  
  return data;


fs.watch(outputDeparts, (eventType, filename) => 
  return new Promise((resolve, reject) => 
    if(!filename) 
      return reject("FILE NAME NOT PROVIDED");
    
    
    let 
      data = fs.readFileSync(filename, 'utf8'),
      result
    ;
    
    try 
      result = JSON.parse(data);
     catch(error) 
      result = data;
    
    
    return resolve(result);
  )
    .then(onNextTrain)
    .catch(err => console.log("error", err))
  ;
);

【讨论】:

只需用 resolve(result) 而不是数据更新它! :)【参考方案2】:

尝试将第二个文件中的代码更改为

var result; 
try 
    result = JSON.parse(data);
 catch (err) 
    console.error(err, data);

因为 SyntaxError: Unexpected end of input 这是 JSON.parse 错误。

在第一个文件中,我看到了潜在的问题 fs.writeFile(outputDeparts, data, function(err) ... 回调函数必须提供有序写入,但您的代码 - 仅记录错误。

Node.js 文档

请注意,在同一个文件上多次使用fs.writeFile 而不等待回调是不安全的。对于这种情况,强烈建议使用fs.createWriteStream

【讨论】:

以上是关于使用 fs 读取文件后解析 Json的主要内容,如果未能解决你的问题,请参考以下文章

读取JSON文件的有效方法?

使用 require vs fs.readFile 读取 json 文件内容

JavaScript - 使用 require 读取 JSON 文件的结果与 fs.readFileSync 不同

使用承诺重构代码以读取文件并将它们转换为 json

如何读取 JSON 文件、更改一些值并保存它。使用 FS/Javascript [重复]

fs读取某个json文件的数据