在Node.js中如何逐字节读取二进制文件

50

在Node.js中读取二进制文件的最佳方式是什么?

我想要访问“头部”中特定字节(小于前100个字节),或逐字节读取文件。

3个回答

74

这是一个使用fs.open()返回的文件描述符对前100个字节进行fs.read()操作的示例:

var fs = require('fs');

fs.open('file.txt', 'r', function(status, fd) {
    if (status) {
        console.log(status.message);
        return;
    }
    var buffer = Buffer.alloc(100);
    fs.read(fd, buffer, 0, 100, 0, function(err, num) {
        console.log(buffer.toString('utf8', 0, num));
    });
});

2
它是utf8而不是utf-8 http://nodejs.org/api/buffer.html#buffer_buf_tostring_encoding_start_end - WebFreak001
1
如果我只有字节缓冲区怎么办? - FluffyBeing
1
请将 status 更改为 error 以与文档兼容。 - mikep
搜索了好几个小时才找到像这样的一个例子。谢谢你!我之前发布了一个相关的问题,然后根据你的帮助制作了一个同步版本。https://dev59.com/Lcr6oIgBc1ULPQZFlsHH#74270070 - Modular

2

这是另一种选项

const fs = require('fs');

const fileName = 'something.bin'

/*
Requirements ex:
Content in 512 bytes chunks. 
Send the 512 bytes packet as a 1024 char string, where each byte is sent as a 
2 hex digits. 
An "addr" field starts from 0 and tracks the offset of the first byte of the 
packet. 
*/
function chunk(s, maxBytes) {
  //! https://nodejs.org/api/buffer.html#buffer_buf_slice_start_end
  /*
    buf.slice([start[, end]])
    start <integer> Where the new Buffer will start. Default: 0.
    end <integer> Where the new Buffer will end (not inclusive). Default: buf.length.
    Returns: <Buffer>
  */

  let buf = Buffer.from(s);  
  const result = [];
  let readBuffer = true
  let startChunkByte = 0
  let endChunkByte = maxBytes
  while(readBuffer) {
    // First round
    startChunkByte === 0 ? endChunkByte = startChunkByte + maxBytes : ""

    //Handle last chunk
    endChunkByte >= buf.length ? readBuffer = false : ""

    // addr: the position of the first bytes.  raw: the chunk of x bytes
    result.push({"addr":startChunkByte,"raw":buf.slice(startChunkByte, endChunkByte).toString('hex')});

    startChunkByte = endChunkByte
    endChunkByte = startChunkByte + maxBytes
  }
  return result;
}

fs.readFile(fileName, (err, data) => {
  if (err) throw err;
  // Let's choose 512 bytes chunks
  const arrBinChunk =  chunk(data, 512)
  arrBinChunk.forEach(element => console.log(element))

  //Tests - should be able to see 1024, 1024, as per riquerements
  arrBinChunk.forEach(element => console.log(element.raw.length))
});

0
使用@samplebias的答案,我发现代码可以更简单,并且使用适当的异步功能。
const { open } = require('fs/promises');

const path = 'some/dir/your-file.txt' // change this to your local file's location
const start = 0 // place the reading cursor in this position
const size = 100 // following the example from the original answer. chnage this to suit your needs

const handler = await open(path, 'r')
const { buffer, bytesRead } = await handler.read(Buffer.alloc(size), 0, size, start)

const value = buffer.toString('utf-8', 0, bytesRead)

console.log(value)

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