在节点js中使用fs保存

时间:2014-08-09 00:46:43

标签: node.js fs

我有以下代码,但我正在努力使用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)

感谢我的支持 - 节点js对我来说。

1 个答案:

答案 0 :(得分: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的内容来执行此操作。