const fs = require('fs');

const filename="binary.bin";

fs.readFile(filename, (err, data) => {
  if (err) {
    console.error('Error reading file:', err);
    return;
  }
  console.log(data);

  // process the Buffer data using Buffer methods (e.g., slice, copy)
});

Transmissão de arquivos em JavaScript

Outra faceta de lidar com arquivos é o streaming em pedaços de dados, o que se torna uma necessidade ao lidar com arquivos grandes. Aqui está um exemplo artificial de escrita em pedaços de streaming:


const fs = require('fs');

const filename="large_file.txt"; 
const chunkSize = 1024 * 1024; // (1)
const content="This is some content to be written in chunks."; // (2)
const fileSizeLimit = 5 * 1024 * 1024; // // (3)

let writtenBytes = 0; // (4)

const writeStream = fs.createWriteStream(filename, { highWaterMark: chunkSize }); // (5)

function writeChunk() { // (6)
  const chunk = content.repeat(Math.ceil(chunkSize / content.length)); // (7)

  if (writtenBytes + chunk.length  fileSizeLimit) {
      console.error('File size limit reached');
      writeStream.end(); 
      return;
    }
    console.log(`Wrote chunk of size: ${chunk.length}, Total written: ${writtenBytes}`);
  }
}

writeStream.on('error', (err) => { // (10)
  console.error('Error writing file:', err);
});

writeStream.on('finish', () => { // (10)
  console.log('Finished writing file');
});

writeChunk(); 

O streaming lhe dá mais poder, mas você notará que envolve mais trabalho. O trabalho que você está fazendo é definir tamanhos de blocos e, em seguida, responder a eventos com base nos blocos. Esta é a essência de evitar colocar muito de um arquivo enorme na memória de uma vez. Em vez disso, você o divide em blocos e lida com cada um. Aqui estão minhas notas sobre as partes interessantes do exemplo de gravação acima:

  1. Especificamos um tamanho de chunk em kilobytes. Neste caso, temos um chunk de 1MB, que é a quantidade de conteúdo que será escrita por vez.
  2. Aqui está algum conteúdo falso para escrever.
  3. Agora, criamos um limite de tamanho de arquivo, neste caso, 5 MB.
  4. Esta variável rastreia quantos bytes escrevemos (para que possamos parar de escrever após 5 MB).
  5. Nós criamos o real writeStream objeto. O highWaterMark elemento informa o tamanho dos pedaços que ele aceitará.
  6. O writeChunk() function é recursiva. Sempre que um pedaço precisa ser manipulado, ela chama a si mesma. Ela faz isso a menos que o limite do arquivo tenha sido atingido, nesse caso ela sai.
  7. Aqui, estamos apenas repetindo o texto de exemplo até que ele atinja o tamanho de 1 MB.
  8. Aqui está a parte interessante. Se o tamanho do arquivo não for excedido, então chamamos writeStream.write(chunk):
    1. writeStream.write(chunk) retorna false se o tamanho do buffer for excedido. Isso significa que não podemos colocar mais no buffer dado o limite de tamanho.
    2. Quando o buffer é excedido, o drain evento ocorre, manipulado pelo primeiro manipulador, que definimos aqui com writeStream.once('drain', writeChunk);. Observe que este é um retorno de chamada recursivo para writeChunk.
  9. Isso registra o quanto escrevemos.
  10. Isso lida com o caso em que terminamos de escrever e finaliza o stream writer com writeStream.end();.
  11. Isso demonstra a adição de manipuladores de eventos para error e finish.

E para lê-lo novamente do disco, podemos usar uma abordagem semelhante: