【问题标题】:Read a file one character at a time in node.js?在node.js中一次读取一个字符的文件?
【发布时间】:2015-07-17 18:25:32
【问题描述】:

有没有办法在 nodejs 中一次从文件中读取一个符号而不将整个文件存储在内存中? 我找到了lines的答案

我尝试了类似的方法,但没有帮助:

const stream = fs.createReadStream("walmart.dump", {
    encoding: 'utf8',
    fd: null,
    bufferSize: 1,
});
stream.on('data', function(sym){
    console.log(sym);
});

【问题讨论】:

    标签: node.js stream


    【解决方案1】:

    可读流有一个read() 方法,您可以在其中传递要读取的每个块的长度(以字节为单位)。例如:

    var readable = fs.createReadStream("walmart.dump", {
        encoding: 'utf8',
        fd: null,
    });
    readable.on('readable', function() {
      var chunk;
      while (null !== (chunk = readable.read(1) /* here */)) {
        console.log(chunk); // chunk is one byte
      }
    });
    

    【讨论】:

      【解决方案2】:

      这是一种较低级别的方法:fs.read(fd, buffer, offset, length, position, callback)

      使用:

      const fs = require('fs');
      
      // open file for reading, returns file descriptor
      const fd = fs.openSync('your-file.txt','r');
      
      function readOneCharFromFile(position, cb){
      
              // only need to store one byte (one character)
              const b = new Buffer(1);
      
              fs.read(fd, b, 0, 1, position, function(err,bytesRead, buffer){
                  console.log('data => ', String(buffer));
                  cb(err,buffer);
              });
      
      }
      

      您必须在读取文件时增加位置,但它会起作用。

      这是一个如何逐个字符读取整个文件的快速示例

      只是为了好玩,我编写了这个完整的脚本来完成它,只需传入不同的文件路径,它应该可以工作

      const async = require('async');
      const fs = require('fs');
      const path = require('path');
      
      
      function read(fd, position, cb) {
      
          let isByteRead = null;
          let ret = new Buffer(0);
      
          async.whilst(
              function () {
                  return isByteRead !== false;
              },
              function (cb) {
                  readOneCharFromFile(fd, position++, function (err, bytesRead, buffer) {
      
                      if(err){
                          return cb(err);
                      }
      
                      isByteRead = !!bytesRead;
                      if(isByteRead){
                          ret = Buffer.concat([ret,buffer]);
                      }
      
                      cb(null);
                  });
              },
              function (err) {
                  cb(err, ret);
              }
          );
      
      }
      
      
      function readOneCharFromFile(fd, position, cb) {
      
          // only need to store one byte (one character)
          const b = new Buffer(1);
          fs.read(fd, b, 0, 1, position, cb);
      
      }
      
      
       /// use your own file here
      const file = path.resolve(__dirname + '/fixtures/abc.txt');
      const fd = fs.openSync(file, 'r');
      
      // start reading at position 0, position will be incremented
      read(fd, 0, function (err, data) {
          if (err) {
              console.error(err.stack || err);
          }
          else {
              console.log('data => ', String(data));
          }
          fs.closeSync(fd);
      });
      

      如您所见,每次读取文件时我们都会增加位置整数。希望操作系统在我们进行时将文件保存在内存中。使用 async.whilst() 是可以的,但我认为对于更实用的样式,最好不要将状态保持在函数的顶部(ret 和 isByteRead)。我将把它作为练习留给读者来实现,而不使用那些有状态的变量。

      【讨论】:

      • fs.openSync 将立即读取整个文件...这与 OP 想要的相反。
      猜你喜欢
      • 2011-09-03
      • 2011-02-28
      • 1970-01-01
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多