【问题标题】:Saving with fs in node js在节点 js 中使用 fs 保存
【发布时间】:2014-08-10 16:57:44
【问题描述】:

我有以下代码,但我正在努力使用fs 将其保存到 csv。任何帮助表示赞赏。我一直在看this

    var request = require('request');
var cheerio = require('cheerio');
var wait = require("wait.for");
var fs = require('fs');

function requestWaitForWrapper(url, callback) {
  request(url, function(error, response, html) {
    if (error)
      callback(error, response);
    else if (response.statusCode == 200)
      callback(null, html);
    else
      callback(new Error("Status not 200 OK"), response);
  });
}

function readBookInfo(baseUrl, s) {
  var html = wait.for(requestWaitForWrapper, baseUrl + '&s=' + s.toString());
  var $ = cheerio.load(html, {
    xmlMode: true
  });

  return {
    s: s,
    id: $('work').attr('id'),
    total: parseInt($('records').attr('total'))
  };
}

function readWorkInfo(id) {
  var html = wait.for(requestWaitForWrapper, 'http://api.trove.nla.gov.au/work/' + id.toString() + '?key=6k6oagt6ott4ohno&reclevel=full');
  var $ = cheerio.load(html, {
    xmlMode: true
  });

  return {
    title: $('title').text(),
    contributor: $('contributor').text(),
    description: $('abstract').text()
  }
}

function main() {
  var baseBookUrl = 'http://api.trove.nla.gov.au/result?key=6k6oagt6ott4ohno&zone=book&l-advformat=Thesis&sortby=dateDesc&q=+date%3A[2000+TO+2014]&l-availability=y&l-australian=y&n=1';
  var baseInfo = readBookInfo(baseBookUrl, 0);

  for (var s = 0; s < baseInfo.total; s++) {
    var bookInfo = readBookInfo(baseBookUrl, s);
    var workInfo = readWorkInfo(bookInfo.id);

    fs.writeFile("Users/name/echojs.csv", bookInfo.id + ";" + workInfo.contributor + ";" + workInfo.description, function (err) {
  if (err) throw err;
  console.log('Save Complete');
});

  }
}

wait.launchFiber(main);

评论后编辑

最后是不是这个意思:

  for (var s = 0; s < baseInfo.total; s++) {
    var bookInfo = readBookInfo(baseBookUrl, s);
    var workInfo = readWorkInfo(bookInfo.id);
    var combined = bookInfo.id+";"+workInfo.contributor+";"+workInfo.description;

    fs.writeFile("Users/name/echojs.csv", combined, function (err) {
  if (err) throw err;
  console.log('Save Complete');
});

  }
}

wait.launchFiber(main)

;

感谢您对我的包容 - node js 是我的。

【问题讨论】:

  • 您遇到了哪些具体错误/问题?
  • 你不能在这样的同步循环中调用fs.writeFile。我建议您在写入之前编写一个存储所有数据的字符串,或者写入use streams
  • 使用 sync 版本的函数应该可以消除您看到的异步问题,例如fs.appendFileSyncdisasterjs.blogspot.cz/2013/03/… 上提供了一些澄清文章,此外,这个 npm 包 github.com/jprichardson/node-fs-extra 实现了一些 sync 文件系统功能,如创建目录等,您可能会发现这些功能很有用

标签: node.js fs


【解决方案1】:

我不知道你遇到了什么确切的错误,但这是我的想法:

我相信您最大的问题是您使用的是 fs.writeFile,但您似乎想将数据附加到文件中。您应该为此使用fs.appendFile - 否则您将始终覆盖您之前编写的内容,这意味着只编写循环的最后一次迭代。

还要注意 fs.writeFile 是异步的,这意味着在您知道数据已写入文件之前,您正在遍历循环。您可以只使用 fs.writeFileSync(或者更确切地说是上面提到的 fs.appendSync),这可以确保文件被写入 - 然后才继续处理代码。但是,这也意味着写入/附加到文件会阻塞您的线程。

一个简单的方法是使用递归函数等待回调完成,然后再次调用自身:

function writeBooks(baseBookUrl, baseInfo, index) {
  if (!index) {
    index = 0;
  }

  var bookInfo = readBookInfo(baseBookUrl, s);
  var workInfo = readWorkInfo(bookInfo.id);
  var combined = bookInfo.id+";"+workInfo.contributor+";"+workInfo.description;

  fs.appendFile("Users/name/echojs.csv", combined, function(error) {
    if (error) {
      console.log("Whoops: " + error);
    }

    writeBooks(baseBookUrl, baseInfo, ++index);
  });
}

这意味着在创建文件的过程中可以处理其他代码,并且文件的内容将按顺序写入(因为您知道前面的信息已经写入)。您也可以使用 async library 之类的东西来执行此操作。

【讨论】:

  • 感谢您的全面解释。我已经尝试将它添加到我上面的代码中并得到SyntaxError: Unexpected token }。另外,您上面的解决方案应该放在我原始代码的末尾吗?
  • @user1222447 糟糕,已修复 - 现在没有语法错误。它应该在你调用var baseInfo = readBookInfo(baseBookUrl, 0); 之后在 main 中调用,因为你需要这 2 个变量来调用该函数。但是,重要的是您要了解它在做什么,因此请对其进行试验。 ;)
  • 我现在得到以下信息:Error: Status not 200 OK at Request._callback (C:\Users\name\trial.js:13:16) at Request.self.callback (C:\Users\name\node_modules\request\request.js:123:2 2) at Request.EventEmitter.emit (events.js:98:17) at Request.&lt;anonymous&gt; (C:\Users\name\node_modules\request\request.js:1047:14 ) at Request.EventEmitter.emit (events.js:117:20) at IncomingMessage.&lt;anonymous&gt; (C:\Users\name\node_modules\request\request.js :998:12) at IncomingMessage.EventEmitter.emit (events.js:117:20) at _stream_readable.js:920:16 at process._tickCallback (node.js:415:13).
  • 这是因为我正在抓取的网站/服务器想要限制我拨打的电话吗?
  • 抱歉,不知道是什么意思。似乎与我的代码无关。你的代码以前工作过但没有写文件吗?我只是回答与 fs 相关的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 2016-02-13
  • 1970-01-01
  • 2014-03-15
  • 2021-12-24
  • 1970-01-01
  • 2021-11-12
相关资源
最近更新 更多