Due domande che dobbiamo porci mentre facciamo tali operazioni sono:
- Qual è la quantità di memoria utilizzata per eseguirla?
- Il consumo di memoria sta aumentando drasticamente con la dimensione del file?
Soluzioni come require('fs').readFileSync()
caricano l'intero file in memoria. Ciò significa che la quantità di memoria richiesta per eseguire le operazioni sarà quasi equivalente alla dimensione del file. Dovremmo evitare questi per qualcosa di più grande di50mbs
Possiamo facilmente tracciare la quantità di memoria utilizzata da una funzione posizionando queste righe di codice dopo l'invocazione della funzione:
const used = process.memoryUsage().heapUsed / 1024 / 1024;
console.log(
`The script uses approximately ${Math.round(used * 100) / 100} MB`
);
In questo momento il modo migliore per leggere righe particolari da un file di grandi dimensioni è usare la readline del nodo . La documentazione contiene esempi sorprendenti .
Sebbene non sia necessario alcun modulo di terze parti per farlo. Ma, se stai scrivendo un codice aziendale, devi gestire molti casi limite. Ho dovuto scrivere un modulo molto leggero chiamato Apick File Storage per gestire tutti quei casi limite.
Modulo di archiviazione file Apick: https://www.npmjs.com/package/apickfs
Documentazione: https://github.com/apickjs/apickFS#readme
File di esempio: https://1drv.ms/t/s!AtkMCsWInsSZiGptXYAFjalXOpUx
Esempio: modulo di installazione
npm i apickfs
// import module
const apickFileStorage = require('apickfs');
//invoke readByLineNumbers() method
apickFileStorage
.readByLineNumbers(path.join(__dirname), 'big.txt', [163845])
.then(d => {
console.log(d);
})
.catch(e => {
console.log(e);
});
Questo metodo è stato testato con successo con file densi fino a 4 GB.
big.text è un file di testo denso con 163.845 righe ed è di 124 Mb. Lo script per leggere 10 righe diverse da questo file utilizza solo circa 4,63 MB di memoria. E analizza gratuitamente JSON valido per oggetti o array. 🥳 Fantastico !!
Possiamo leggere una singola riga del file o centinaia di righe del file con un consumo di memoria molto ridotto.
fs.readSync()
. È possibile leggere ottetti binari in un buffer, ma non esiste un modo semplice per gestire i caratteri UTF-8 o UTF-16 parziali senza ispezionare il buffer prima di tradurlo in stringhe JavaScript e scansionare EOL. IlBuffer()
tipo non ha un set completo di funzioni per operare sulle sue istanze come stringhe native, ma le stringhe native non possono contenere dati binari. Mi sembra che la mancanza di un modo integrato per leggere righe di testo da filehandle arbitrari sia un vero gap in node.js.