【问题标题】:Write objects into file with Node.js使用 Node.js 将对象写入文件
【发布时间】:2014-03-25 10:55:00
【问题描述】:

我已经在 stackoverflow / google 上搜索了这个,但似乎无法弄清楚。

我正在抓取给定 URL 页面的社交媒体链接,该函数返回一个带有 URL 列表的对象。

当我尝试将此数据写入另一个文件时,它会以[object Object] 的形式输出到文件中,而不是预期的: ['https://twitter.com/#!/101Cookbooks', 'http://www.facebook.com/101cookbooks'] 就像我 console.log() 结果一样。

这是我在 Node 中读取和写入文件的悲伤尝试,尝试读取每一行(url)并通过函数调用request(line, gotHTML) 输入:

fs.readFileSync('./urls.txt').toString().split('\n').forEach(function (line){
    console.log(line); 
    var obj = request(line, gotHTML); 
    console.log(obj); 
    fs.writeFileSync('./data.json', obj , 'utf-8'); 
});   

供参考——gotHTML 函数:

function gotHTML(err, resp, html){ 
    var social_ids = []; 

    if(err){
        return console.log(err); 
    } else if (resp.statusCode === 200){ 
        var parsedHTML = $.load(html); 

        parsedHTML('a').map(function(i, link){
            var href = $(link).attr('href');
            for(var i=0; i<socialurls.length; i++){
                if(socialurls[i].test(href) && social_ids.indexOf(href) < 0 ) {
                    social_ids.push(href); 
                }; 
            }; 
        })
    };

    return social_ids;
};

【问题讨论】:

  • [object Object] 是一个对象toString。如果您想要对象的表示,请使用JSON.stringify
  • 小心JSON.stringify。使用数组是安全的,但是当对象具有循环引用时,它将失败 (see this topic)。 util 模块处理循环引用。

标签: javascript node.js file-io


【解决方案1】:

在 deb2fast 所说的基础上,我还将向 JSON.stringify() 传递几个额外的参数以使其成为漂亮的格式:

fs.writeFileSync('./data.json', JSON.stringify(obj, null, 2) , 'utf-8');

第二个参数是一个可选的替换函数,在这种情况下你不需要它,所以null 可以工作。

第三个参数是用于缩进的空格数。 2 和 4 似乎是流行的选择。

【讨论】:

  • 会导致循环依赖问题。双向依赖无法转换为 JSON。
  • 写入的文本文件缺少文件末尾的换行符。有什么办法解决这个问题?
  • @friederbluemle - 你可以 + '\n' 到那个 stringify() 调用来添加那个换行符。
  • 这个对我来说效果最好,因为使用接受的答案给了我错误的结果。
【解决方案2】:

obj 在您的示例中是一个数组。

fs.writeFileSync(filename, data, [options]) 在 data 参数中需要 StringBuffersee docs.

尝试将数组写成字符串格式:

// writes 'https://twitter.com/#!/101Cookbooks', 'http://www.facebook.com/101cookbooks'
fs.writeFileSync('./data.json', obj.join(',') , 'utf-8'); 

或者:

// writes ['https://twitter.com/#!/101Cookbooks', 'http://www.facebook.com/101cookbooks']
var util = require('util');
fs.writeFileSync('./data.json', util.inspect(obj) , 'utf-8');

编辑:您在示例中看到数组的原因是因为节点的console.log 实现不只是调用toString,它调用util.format see console.js source

【讨论】:

  • 如果您的对象包含大型数组,这将不起作用,因为检查方法将输出类似“45000 more...]”的内容
【解决方案3】:

如果您收到[object object],请使用JSON.stringify

fs.writeFile('./data.json', JSON.stringify(obj) , 'utf-8');

它对我有用。

【讨论】:

    【解决方案4】:

    根据我的经验,JSON.stringify 比 util.inspect 稍快。 我不得不将 DB2 查询的结果对象保存为 json 文件,查询返回一个 92k 行的对象,使用 util.inspect 完成转换需要很长时间,所以我通过编写相同的 1000 记录对象进行了以下测试使用这两种方法复制到一个文件中。

    1. JSON.Stringify

      fs.writeFile('./data.json', JSON.stringify(obj, null, 2));
      

    时间:3:57(3 分 57 秒)

    结果格式:

    [
      {
        "PROB": "00001",
        "BO": "AXZ",
        "CNTRY": "649"
       },
      ...
    ]
    
    1. util.inspect

      var util = require('util');
      fs.writeFile('./data.json', util.inspect(obj, false, 2, false));
      

    时间:4:12(4 分 12 秒)

    结果格式:

    [ { PROB: '00001',
        BO: 'AXZ',
        CNTRY: '649' },
        ...
    ]
    

    【讨论】:

      【解决方案5】:

      你可以试试 JSON.stringify(obj);

      这样

       var stringify = JSON.stringify(obj);
      fs.writeFileSync('./data.json', stringify , 'utf-8'); 
      

      【讨论】:

        【解决方案6】:

        以防其他人偶然发现这一点,我在节点中使用 fs-extra 库并将 javascript 对象写入如下文件:

        const fse = require('fs-extra');
        fse.outputJsonSync('path/to/output/file.json', objectToWriteToFile); 
        

        【讨论】:

          【解决方案7】:

          进一步了解@Jim Schubert@deb2fast 的答案:

          为了能够写出比~100 MB大的订单objects,您需要使用for...of,如下所示并符合您的要求。

          const fsPromises = require('fs').promises;
          
          const sampleData = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
          
          const writeToFile = async () => {
            for (const dataObject of Object.keys(sampleData)) {
                console.log(sampleData[dataObject]);
                await fsPromises.appendFile( "out.json" , dataObject +": "+ JSON.stringify(sampleData[dataObject]));
            }
          }
          
          writeToFile();

          请参阅 https://stackoverflow.com/a/67699911/3152654 以获取有关 node.js 限制的完整参考

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-05-15
            • 2017-11-28
            • 1970-01-01
            • 1970-01-01
            • 2017-06-29
            • 1970-01-01
            相关资源
            最近更新 更多