Node.js/读取文件的前100个字节

17

我正在尝试分部分读取文件:首先是前100个字节,然后是接下来的内容。
我正在尝试读取/npm文件的前100个字节:

app.post('/random', function(req, res) {
    var start = req.body.start;
    var fileName = './npm';
    var contentLength = req.body.contentlength;
    var file = randomAccessFile(fileName + 'read');
    console.log("Start is: " + start);
    console.log("ContentLength is: " + contentLength);
    fs.open(fileName, 'r', function(status, fd) {
        if (status) {
            console.log(status.message);
            return;
        }
        var buffer = new Buffer(contentLength);
        fs.read(fd, buffer, start, contentLength, 0, function(err, num) {
            console.log(buffer.toString('utf-8', 0, num));
        });
    });

输出结果为:

Start is: 0
ContentLength is: 100

还有下一个错误:

fs.js:457
  binding.read(fd, buffer, offset, length, position, wrapper);
          ^
Error: Length extends beyond buffer
    at Object.fs.read (fs.js:457:11)
    at C:\NodeInst\node\FileSys.js:132:12
    at Object.oncomplete (fs.js:107:15)

可能的原因是什么?

2个回答

24

你把offsetposition这两个参数搞混了。根据文档:

offset是缓冲区中开始写入的偏移量。

position是一个整数,指定从文件中开始读取的位置。如果position为空,则数据将从当前文件位置读取。

你需要修改你的代码为:

    fs.read(fd, buffer, 0, contentLength, start, function(err, num) {
        console.log(buffer.toString('utf-8', 0, num));
    });

基本上,offset 是 fs.read 将要写入缓冲区的索引。假设你有一个长度为10的缓冲区,像这样:<Buffer 01 02 03 04 05 06 07 08 09 0a>,然后你将从 /dev/zero 中读取(该设备基本上只包含零),并将偏移量设置为3,长度设置为4,那么你将得到这个结果:<Buffer 01 02 03 00 00 00 00 08 09 0a>

fs.open('/dev/zero', 'r', function(status, fd) {
    if (status) {
        console.log(status.message);
        return;
    }
    var buffer = new Buffer([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    fs.read(fd, buffer, 3, 4, 0, function(err, num) {
        console.log(buffer);
    });
});

此外,如果你想要制作一些东西,你可能想尝试使用fs.createReadStream

app.post('/random', function(req, res) {
    var start = req.body.start;
    var fileName = './npm';
    var contentLength = req.body.contentlength;
    fs.createReadStream(fileName, { start : start, end: contentLength - 1 })
        .pipe(res);
});

2
不要忘记关闭文件描述符:fs.close(fd); - Finesse

5
自 Node 10 版本起,引入了实验性的 Readable[Symbol.asyncIterator] 特性(在 Node v12 中已不再是实验性特性)。
'use strict';

const fs = require('fs');

async function run() {
  const file = 'hello.csv';
  const stream = fs.createReadStream(file, { encoding: 'utf8', start: 0, end: 100 });
  for await (const chunk of stream) {
    console.log(`${file} >>> ${chunk}`);
  }

  // or if you don't want the for-await-loop
  const stream = fs.createReadStream(file, { encoding: 'utf8', start: 0, end: 100 });
  const firstByte = await stream[Symbol.asyncIterator]().next();
  console.log(`${file} >>> ${firstByte.value}`);
}

run();

将打印出前几个字节


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接