Google Drive Api v3 获取下载进度
Google Drive Api v3 get download progress
当从我的 Nodejs 脚本下载时,我正在尝试获取存储在我的 Google 驱动器单元中的大文件的下载进度百分比。
到目前为止,我已经编写了下载代码,可以正常工作,但是从未调用 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)
.
.
.
当从我的 Nodejs 脚本下载时,我正在尝试获取存储在我的 Google 驱动器单元中的大文件的下载进度百分比。
到目前为止,我已经编写了下载代码,可以正常工作,但是从未调用 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)
.
.
.