Glo*_*omy 9 javascript xmlhttprequest fetch node.js fetch-api
我有一个可能很大的文件(100+ Mb)的url,如何使用访存将其保存在本地目录中?
我环顾四周,但是关于如何执行此操作似乎没有很多资源/教程。
谢谢!
ant*_*nok 40
这里较旧的答案涉及node-fetch,但因为Node.js v18.x这可以在没有额外依赖的情况下完成。
获取响应的主体是一个网络流。fs可以使用将其转换为 Node流Readable.fromWeb,然后将其通过管道传输到由 创建的写入流中fs.createWriteStream。如果需要,可以将生成的流转换为Promise使用 Promise 版本的stream.finished.
const fs = require('fs');
const { Readable } = require('stream');
const { finished } = require('stream/promises');
const stream = fs.createWriteStream('output.txt');
const { body } = await fetch('https://example.com');
await finished(Readable.fromWeb(body).pipe(stream));
Run Code Online (Sandbox Code Playgroud)
Ahm*_*sih 17
如果您想避免像在另一个非常好的答案中那样显式地创建 Promise,并且可以构建整个 100+ MB 文件的缓冲区,那么您可以做一些更简单的事情:
const fetch = require('node-fetch');
const {writeFile} = require('fs');
const {promisify} = require('util');
const writeFilePromise = promisify(writeFile);
function downloadFile(url, outputPath) {
return fetch(url)
.then(x => x.arrayBuffer())
.then(x => writeFilePromise(outputPath, Buffer.from(x)));
}
Run Code Online (Sandbox Code Playgroud)
但另一个答案将更节省内存,因为它将接收到的数据流直接通过管道传输到文件中,而不会将所有数据流累积到缓冲区中。
小智 11
使用Fetch API,您可以编写一个可以从如下网址下载的函数:
const downloadFile = (async (url, path) => {
const res = await fetch(url);
const fileStream = fs.createWriteStream(path);
await new Promise((resolve, reject) => {
res.body.pipe(fileStream);
res.body.on("error", (err) => {
reject(err);
});
fileStream.on("finish", function() {
resolve();
});
});
});
Run Code Online (Sandbox Code Playgroud)
Iho*_*yuk 11
const {createWriteStream} = require('fs');
const {pipeline} = require('stream/promises');
const fetch = require('node-fetch');
const downloadFile = async (url, path) => pipeline(
(await fetch(url)).body,
createWriteStream(path)
);
Run Code Online (Sandbox Code Playgroud)