【问题标题】:Why is my fs.readFile returning a buffer instead of XML?为什么我的 fs.readFile 返回的是缓冲区而不是 XML?
【发布时间】:2017-04-01 18:24:51
【问题描述】:

我有一个名为 fetchXML 的函数,它假设将一个 XML 文件写入我的名为 feed.xml 的根目录,然后我想控制台记录 feed.xml 中的数据。我使用 fs.readFile 并使用 'utf-8' 指定编码,如以下问题所示:Why does Node.js' fs.readFile() return a buffer instead of string?

但我的 console.log 的结果仍然是一个缓冲区。我检查了 feed.xml,它确实包含 xml。

var out = fs.createWriteStream('./feed.xml');

var fetchXML = function() {
  var feedURL = 'http://www2.jobs2careers.com/feed.php?id=1237-2595&c=1&pass=HeahE0W1ecAkkF0l';
  var stream = request(feedURL).pipe(zlib.createGunzip()).pipe(out);

  stream.on('finish', function() {
    fs.readFile('./feed.xml', 'utf-8', function(err, data) {
      console.log(data);
    });
  });
}

fetchXML();

【问题讨论】:

  • 什么节点版本?
  • 最新的实验功能。 7.1
  • 我假设从 readFile 返回的错误为空?另外,输出是否正确(除了作为缓冲区而不是字符串)?
  • 没有错误,但是我不知道如何回答你关于缓冲区是否正确的问题,我只知道它是一个缓冲区而不是包含xml的字符串。
  • 我的意思是,对于您期望的 xml,字节是正确的 ascii 吗?另外,您使用的是什么 zlib 库?

标签: xml node.js


【解决方案1】:

这里的主要问题是在这种情况下设置了err,它会告诉您toString() 失败(由于文件的大小)。然后它将读取的数据保留为 Buffer 并将其作为第二个参数传递给回调。

这可能被视为部分错误,因为大多数人可能不希望看到第二个参数传入,但同时 err is 设置(并且您应该始终处理错误) 并且它确实让您有机会对已经读入内存的(原始二进制)数据执行其他操作。

就解决方案而言,您可能需要一个流式解析器来处理像这样的大量数据(数百兆字节)。对于 XML,提供流式接口的模块之一是 node-expat

【讨论】:

  • 我想获取 xml 并使用 xml2js 将其转换为 JSON,但是当我尝试使用“数据”时它返回未定义而不是 JSON。我认为这可能与它返回缓冲区有关。
  • 您将需要对非常大的文档使用流式解析器,正如我现在在回答中所指出的那样。
  • 我到底想用流解析器完成什么?老实说,为什么我目前的解决方案不起作用,我有点困惑。我以前从来没有做过这样的事情,所以你必须回到一个基本的解释。
  • V8 有一个最大字符串大小,当您要求节点将原始二进制数据转换为 JavaScript 字符串时,它会因为数据太大而失败。在这种特殊情况下,XML 数据超过 300mb,V8's current max string size 约为 268mb。如果您使用流式解析器,您可以逐块解析 XML 块,而不是尝试先将整个 XML 文件加载为一个巨大的字符串然后解析它。
  • 好的,这是有道理的。对于 node-expat,我需要使用哪个函数?我看到了各种各样的 startElement、endElement 等,但如何使用它们并不是完全不言自明...
猜你喜欢
  • 2011-09-21
  • 2022-11-28
  • 2014-12-03
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多