如何解决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
},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)
.
.
.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。