Google Drive Api v3获取下载进度



从Nodejs脚本下载时,我正试图获得存储在Google Drive单元中的一个巨大文件的下载进度%。

到目前为止,我已经编写了要下载的代码,它正在运行,但从未调用过on('data'....)部分。

const downloadFile = (file) => {
const fileId = file.id;
const fileName = path.join(basePathForStorage, file.name);
const drive = google.drive({ version: 'v3', authorization });
let progress = 0;
return new Promise((resolve, reject) => { 
drive.files.get(
{
auth: authorization,
fileId: fileId,
alt: 'media'
},
{ responseType: "arraybuffer" },
function (err, { data }) {

fs.writeFile(fileName, Buffer.from(data), err => {

// THIS PART DOES NOTHING
data.on('data',(d)=>{
progress += d.length;
console.log(`Progress: ${progress}`)
})
// --------------------
if (err) {
console.log(err);
return reject(err);
}
return resolve(fileName)
});
}
);
});
}

看起来我找不到通过调用on('data'....)来显示下载进度的方法。。。现在想知道这是否是正确的方法,或者这是否可能。

我尝试将on('data'....)代码放入writeFile函数中,但也放入drive.files.get的回调中,但没有任何效果。

这里有一些代码示例,
这个示例有三个部分需要提及:

  • 创建一个流来跟踪我们的下载进度
  • 创建一个获取文件大小的方法
  • 创建一个事件发射器,将我们的进度发送回FE

因此我们将得到以下内容:

const downloadFile = async(file) => {
const fileId = file.id
const fileName = path.join(basePathForStorage, file.name)

let progress = 0
/**
* ATTENTION: here you shall specify where your file will be saved, usually a .temp folder
* Here we create the stream to track our download progress
*/
const fileStream = fs.createWriteStream(path.join(__dirname, './temp/', filename))
const fileSize = await getFileSize(file)
// In here we listen to the stream writing progress 
fileStream.on('data', (chunk) => {
progress += chunk.length / fileSize
console.log('progress', progress)
})
const drive = google.drive({
version: 'v3',
authorization
})
drive.files.get({
auth: authorization,
fileId: fileId,
alt: 'media'
}, {
responseType: "stream"
},
(err, { data }) => 
data
.on('end', () => console.log('onCompleted'))
.on('error', (err) => console.log('onError', err))
.pipe(fileStream)
)
}

检索文件大小的方法:

const getFileSize = ({ fileId: id }) => {
const drive = google.drive({
version: 'v3',
authorization
})
return new Promise((resolve, reject) => 
drive.files.get({ 
auth: authorization,
fileId
}, (err, metadata) {
if (err) return reject(err)
else resolve(metadata.size)
})
}

此代码示例使您能够在创建写流(nodejs#createWriteStream(时从文件下载中获得部分更新
因此您将能够跟踪文件下载进度。

但是,您仍然必须不断地将这些更改发送给您的客户(FE(
因此,您可以创建自己的EventEmitter来跟踪它。

现在,我们的样品将添加以下内容:

在我们的终点:

import { EventEmitter } from 'events'
router.post('/myEndpoint', (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' })
const progressEvent = new EventEmitter()
progressEvent.on('progress', (progress) => {
if (progress === 100)
res.end()
// So, your FE side will be receiving this message continuosly
else res.write(`{ progress: ${ progress } }`)
})
const file = req.body // or where you're getting your file from
downloadFile(file, progressEvent)
})

在我们的下载方法:

const downloadFile = async(file, progressEvent) => {
.
.
.
fileStream.on('data', (chunk) => {
progress += chunk.length / fileSize
progressEvent.emit('progress', progress)
.
.
.

最新更新