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:
- 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.
- Aqui está algum conteúdo falso para escrever.
- Agora, criamos um limite de tamanho de arquivo, neste caso, 5 MB.
- Esta variável rastreia quantos bytes escrevemos (para que possamos parar de escrever após 5 MB).
- Nós criamos o real
writeStream
objeto. OhighWaterMark
elemento informa o tamanho dos pedaços que ele aceitará. - 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. - Aqui, estamos apenas repetindo o texto de exemplo até que ele atinja o tamanho de 1 MB.
- Aqui está a parte interessante. Se o tamanho do arquivo não for excedido, então chamamos
writeStream.write(chunk)
:writeStream.write(chunk)
retornafalse
se o tamanho do buffer for excedido. Isso significa que não podemos colocar mais no buffer dado o limite de tamanho.- Quando o buffer é excedido, o
drain
evento ocorre, manipulado pelo primeiro manipulador, que definimos aqui comwriteStream.once('drain', writeChunk);
. Observe que este é um retorno de chamada recursivo parawriteChunk
.
- Isso registra o quanto escrevemos.
- Isso lida com o caso em que terminamos de escrever e finaliza o stream writer com
writeStream.end();
. - Isso demonstra a adição de manipuladores de eventos para
error
efinish
.
E para lê-lo novamente do disco, podemos usar uma abordagem semelhante: