使用 Node.js 将对象写入文件

Posted

技术标签:

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

我已经在 *** / 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 模块处理循环引用。 【参考方案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 参数中需要 StringBuffer。 see 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 记录对象进行了以下测试使用这两种方法复制到一个文件中。

    JSON.Stringify

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

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

结果格式:

[
  
    "PROB": "00001",
    "BO": "AXZ",
    "CNTRY": "649"
   ,
  ...
]

    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://***.com/a/67699911/3152654 以获取有关 node.js 限制的完整参考

【讨论】:

以上是关于使用 Node.js 将对象写入文件的主要内容,如果未能解决你的问题,请参考以下文章

Node.Js 向文件写入和读取数组

使用 Node.js 将一行写入 .txt 文件

使用 Node.js 将 json 文件写入 Firebase?

Node.js写入YAML文件

在 Node.js 中事务性地写入文件

Node.js的Buffer写入