node.js axios 下载文件流并写入文件 [英] node.js axios download file stream and writeFile

查看:233
本文介绍了node.js axios 下载文件流并写入文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用 axios 下载一个 pdf 文件,并用 fs.writeFile 保存在磁盘(服务器端)上,我试过:

axios.get('https://xxx/my.pdf', {responseType: 'blob'}).then(response => {fs.writeFile('/temp/my.pdf', response.data, (err) => {如果(错误)抛出错误;console.log('文件已保存!');});});

文件已保存但内容已损坏...

如何正确保存文件?

解决方案

实际上,我认为之前接受的答案有一些缺陷,因为它无法正确处理写入流,因此如果您调用then()"在 Axios 给你回复后,你最终会得到一个部分下载的文件.

当下载稍大的文件时,这是一个更合适的解决方案:

export async function downloadFile(fileUrl: string, outputLocationPath: string) {const writer = createWriteStream(outputLocationPath);返回 Axios({方法:'获取',网址:文件网址,响应类型:'流',}).那么(响应=> {//确保用户只有在文件已经存在时才能调用`then()`//已完全下载.返回新的承诺((解决,拒绝)=> {response.data.pipe(writer);让错误 = 空;writer.on('错误', err => {错误 = 错误;writer.close();拒绝(错误);});writer.on('close', () => {如果(!错误){解决(真);}//这里不需要调用reject,因为它会在//'错误'流;});});});}

这样,你可以调用downloadFile(),对返回的promise调用then(),确保下载的文件已经完成处理.>

或者,如果你使用更现代的 NodeJS 版本,你可以试试这个:

import * as stream from 'stream';从'util'导入{promisify};const 完成 = promisify(stream.finished);导出异步函数 downloadFile(fileUrl: string, outputLocationPath: string): Promise{const writer = createWriteStream(outputLocationPath);返回 Axios({方法:'获取',网址:文件网址,响应类型:'流',}).then(异步响应=>{response.data.pipe(writer);返回完成(作家);//这是一个承诺});}

i want download a pdf file with axios and save on disk (server side) with fs.writeFile, i have tried:

axios.get('https://xxx/my.pdf', {responseType: 'blob'}).then(response => {
    fs.writeFile('/temp/my.pdf', response.data, (err) => {
        if (err) throw err;
        console.log('The file has been saved!');
    });
});

the file is saved but the content is broken...

how do I correctly save the file?

解决方案

Actually, I believe the previously accepted answer has some flaws, as it will not handle the writestream properly, so if you call "then()" after Axios has given you the response, you will end up having a partially downloaded file.

This is a more appropriate solution when downloading slightly larger files:

export async function downloadFile(fileUrl: string, outputLocationPath: string) {
  const writer = createWriteStream(outputLocationPath);

  return Axios({
    method: 'get',
    url: fileUrl,
    responseType: 'stream',
  }).then(response => {

    //ensure that the user can call `then()` only when the file has
    //been downloaded entirely.

    return new Promise((resolve, reject) => {
      response.data.pipe(writer);
      let error = null;
      writer.on('error', err => {
        error = err;
        writer.close();
        reject(err);
      });
      writer.on('close', () => {
        if (!error) {
          resolve(true);
        }
        //no need to call the reject here, as it will have been called in the
        //'error' stream;
      });
    });
  });
}

This way, you can call downloadFile(), call then() on the returned promise, and making sure that the downloaded file will have completed processing.

Or, if you use a more modern version of NodeJS, you can try this instead:

import * as stream from 'stream';
import { promisify } from 'util';

const finished = promisify(stream.finished);

export async function downloadFile(fileUrl: string, outputLocationPath: string): Promise<any> {
  const writer = createWriteStream(outputLocationPath);
  return Axios({
    method: 'get',
    url: fileUrl,
    responseType: 'stream',
  }).then(async response => {
    response.data.pipe(writer);
    return finished(writer); //this is a Promise
  });
}

这篇关于node.js axios 下载文件流并写入文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆