NodeJS 从Drive API v3下载映像时会不断出现损坏的映像,我应该如何解码承诺的响应?

nzkunb0c  于 2023-02-08  发布在  Node.js
关注(0)|答案(3)|浏览(102)

我正在尝试使用API v3从Google共享驱动器下载图像。下载会成功,但看不到图像。从MacOS Finder打开图像只会出现一个微调器。我开始使用文档中的示例(此处:https://developers.google.com/drive/api/v3/manage-downloads):

const drive = google.drive({version: 'v3', auth});

// ....

var fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
var dest = fs.createWriteStream('/tmp/photo.jpg');
drive.files.get({
  fileId: fileId,
  alt: 'media'
})
    .on('end', function () {
      console.log('Done');
    })
    .on('error', function (err) {
      console.log('Error during download', err);
    })
    .pipe(dest);

但是,由于. on()方法不存在,该操作失败。确切的错误为**"TypeError:驱动器.文件. get(...). on不是函数"**
该. get()方法返回一个promise。promise的响应包含数据,根据配置,可以是流、blob或arraybuffer。对于所有选项,当我将响应数据写入文件时,文件本身变得不可见,并且大小错误。实际代码(typescript,node.js)下面是arraybuffer的例子,blob(添加了name和modifiedDate)和stream的类似代码给出了相同的结果。

const downloader = googleDrive.files.get({
            fileId: file.id,
            alt: 'media',
        }, {
            responseType: 'arraybuffer',
        });

        return downloader
            .then((response) => {

                const targetFile = file.id + '.' + file.extension;

                fs.writeFileSync(targetFile, response.data);

                return response.status;
            })
            .catch((response) => {
                    logger.error('Error in Google Drive service download: ' + response.message);
                    return response.message;
                }
            );
    }

所以问题是:

  • 通过Google云端硬盘API v3处理下载的正确方法是什么?
  • 我需要处理响应数据的任何格式吗?

所有的帮助非常感谢!谢谢

w6mmgewl

w6mmgewl1#

  • 您想要使用Googleapis和Node.js从Google云端硬盘下载文件。
  • 您已经能够使用Drive API。

如果我的理解正确的话,这个答案怎么样?

模式1:

在此模式中,arraybuffer用于表示responseType

示例脚本:

const drive = google.drive({ version: "v3", auth });
var fileId = '###';  // Please set the file ID.
drive.files.get(
  {
    fileId: fileId,
    alt: "media"
  },
  { responseType: "arraybuffer" },
  function(err, { data }) {
    fs.writeFile("sample.jpg", Buffer.from(data), err => {
      if (err) console.log(err);
    });
  }
);
  • 在这种情况下,使用Buffer.from()

模式2:

在此模式中,stream用于表示responseType

示例脚本:

const drive = google.drive({ version: "v3", auth });
var fileId = '###';  // Please set the file ID.
var dest = fs.createWriteStream("sample.jpg");
drive.files.get(
  {
    fileId: fileId,
    alt: "media"
  },
  { responseType: "stream" },
  function(err, { data }) {
    data
      .on("end", () => {
        console.log("Done");
      })
      .on("error", err => {
        console.log("Error during download", err);
      })
      .pipe(dest);
  }
);

备注:

  • 如果出现错误,请使用最新版本的googleapis。
  • 从您的问题中可以看出,您已经能够使用请求获取要下载的文件,但无法打开文件内容。但如果出现错误,请尝试在请求中添加supportsAllDrives: true和/或supportsTeamDrives: true

参考文献:

如果我误解了你的问题,这不是你想要的方向,我道歉。

i86rm4rw

i86rm4rw2#

使用async/await并包含teamdrive文件发布第三个模式以确保完整性。

async function downloadFile(drive: Drive, file: Schema$File, localDir: string = "/tmp/downloads") {
  if (!fs.existsSync(localDir)) {
    fs.mkdirSync(localDir)
  }

  const outputStream = fs.createWriteStream(`${localDir}/${file.name}`);

  const { data } = await drive.files.get({
    corpora: 'drive',
    includeItemsFromAllDrives: true,
    supportsAllDrives: true,
    fileId: file.id,
    alt: "media",
  }, {
    responseType: 'stream',
  })

  await pipeline(data, outputStream)

  console.log(`Downloaded file: ${localDir}/${file.name}`)
}
yeotifhr

yeotifhr3#

如果有人正在寻找一个解决方案是2023年,在这里你去!

const downloadFile = async (file) => {
const dirPath = path.join(process.cwd(), '/images');

if (!fs.existsSync(dirPath)) {
  fs.mkdirSync(dirPath, { recursive: true });
}

const filePath = `${dirPath}/${file.name}.jpg`;
const destinationStream = fs.createWriteStream(filePath);

try {
  const service = await getService();

  const { data } = await service.files.get(
    { fileId: file.id, alt: 'media' },
    { responseType: 'stream' }
  );

  return new Promise((resolve, reject) => {
    data
      .on('end', () => {
        console.log('Done downloading file.');
        resolve(filePath);
      })
      .on('error', (err) => {
        console.error('Error downloading file.');
        reject(err);
      })
      .pipe(destinationStream);
    });
  } catch (error) {
    throw error;
  }
};

相关问题