Mi sono imbattuto in questa pagina mentre cercavo di risolvere un problema in NodeJS: riassemblaggio di blocchi di file. Fondamentalmente: ho una serie di nomi di file. Devo aggiungere tutti quei file, nell'ordine corretto, per creare un file di grandi dimensioni. Devo farlo in modo asincrono.
Il modulo 'fs' del nodo fornisce appendFileSync ma non volevo bloccare il server durante questa operazione. Volevo usare il modulo fs.promises e trovare un modo per concatenare queste cose. Gli esempi in questa pagina non hanno funzionato abbastanza per me perché in realtà avevo bisogno di due operazioni: fsPromises.read () per leggere nel blocco di file e fsPromises.appendFile () per concatenare il file di destinazione. Forse se fossi stato meglio con JavaScript avrei potuto far funzionare le risposte precedenti per me. ;-)
Mi sono imbattuto in questo ...
https://css-tricks.com/why-using-reduce-to-sequentially-resolve-promises-works/
... e sono stato in grado di hackerare insieme una soluzione funzionante.
TLDR:
/**
* sequentially append a list of files into a specified destination file
*/
exports.append_files = function (destinationFile, arrayOfFilenames) {
return arrayOfFilenames.reduce((previousPromise, currentFile) => {
return previousPromise.then(() => {
return fsPromises.readFile(currentFile).then(fileContents => {
return fsPromises.appendFile(destinationFile, fileContents);
});
});
}, Promise.resolve());
};
Ed ecco un test unitario al gelsomino per questo:
const fsPromises = require('fs').promises;
const fsUtils = require( ... );
const TEMPDIR = 'temp';
describe("test append_files", function() {
it('append_files should work', async function(done) {
try {
// setup: create some files
await fsPromises.mkdir(TEMPDIR);
await fsPromises.writeFile(path.join(TEMPDIR, '1'), 'one');
await fsPromises.writeFile(path.join(TEMPDIR, '2'), 'two');
await fsPromises.writeFile(path.join(TEMPDIR, '3'), 'three');
await fsPromises.writeFile(path.join(TEMPDIR, '4'), 'four');
await fsPromises.writeFile(path.join(TEMPDIR, '5'), 'five');
const filenameArray = [];
for (var i=1; i < 6; i++) {
filenameArray.push(path.join(TEMPDIR, i.toString()));
}
const DESTFILE = path.join(TEMPDIR, 'final');
await fsUtils.append_files(DESTFILE, filenameArray);
// confirm "final" file exists
const fsStat = await fsPromises.stat(DESTFILE);
expect(fsStat.isFile()).toBeTruthy();
// confirm content of the "final" file
const expectedContent = new Buffer('onetwothreefourfive', 'utf8');
var fileContents = await fsPromises.readFile(DESTFILE);
expect(fileContents).toEqual(expectedContent);
done();
}
catch (err) {
fail(err);
}
finally {
}
});
});
Spero che aiuti qualcuno.