Cloud Function下载URL后上传Cloud Storage文件为空问题
解决Cloud Function中下载文件后上传至Cloud Storage为空的问题
你遇到的核心问题是异步操作没有正确等待执行完成,导致上传文件的时候,下载操作还没完成,所以/tmp里的文件是空的,上传后自然只有20B的空文件。而且你日志里的file downloaded其实是在下载开始前就打印了,根本不是下载完成的标志。
先给你修正后的完整可运行代码:
const { Storage } = require('@google-cloud/storage'); const http = require('http'); const fs = require('fs'); const { promisify } = require('util'); const pipeline = promisify(require('stream').pipeline); exports.writeToBucket = async (req, res) => { try { const fileStream = fs.createWriteStream("/tmp/pp-monthly-update.txt"); const downloadUrl = "http://prod.publicdata.landregistry.gov.uk.s3-website-eu-west-1.amazonaws.com/pp-monthly-update.txt"; // 把http.get的回调式操作包装成Promise,等待下载完成 await new Promise((resolve, reject) => { const request = http.get(downloadUrl, (response) => { // 使用stream.pipeline处理流,比直接pipe更可靠,能处理错误 pipeline(response, fileStream) .then(resolve) .catch(reject); }); request.on('error', reject); }); console.log('file downloaded'); // 初始化Storage客户端(只需要初始化一次) const storage = new Storage(); const bucketName = 'landregistry_pricepaid_month'; const filename = '/tmp/pp-monthly-update.txt'; // 等待上传操作完成 await storage.bucket(bucketName).upload(filename, { gzip: true, metadata: { cacheControl: 'no-cache', }, }); res.status(200).send(`${filename} uploaded to ${bucketName}.`); } catch (err) { console.error('操作出错:', err); res.status(500).send('操作失败,请查看日志'); } };
关键改进点说明:
- 改用async/await处理异步流程:把导出的函数声明为
async,这样可以用await等待所有异步操作完成,避免"先上传后下载"的顺序错误。 - 包装http.get为Promise:原生
http.get是基于回调的,我们把它包装成Promise,确保只有当文件完全下载写入到/tmp后,才会执行后续的上传操作。 - 使用stream.pipeline替代直接pipe:
pipeline是Node.js官方推荐的流处理方式,它能更好地处理流的错误、自动清理资源,比直接用response.pipe(file)更可靠。 - 移除重复的模块导入:你之前在函数内部重复导入了
Storage,把它移到顶部只导入一次即可。 - 添加错误捕获:用try/catch包裹所有操作,一旦出错可以返回500状态码并打印错误日志,方便排查问题。
为什么之前的代码会出现空文件?
你原来的代码里,http.get和storage.upload都是异步操作,代码会直接跳过它们继续执行res.status(200).send(...),这时候文件还在下载过程中,甚至可能还没写入任何内容,上传的自然是空文件。日志里的file downloaded也是在下载请求刚发起就打印了,不是真的下载完成。
现在修正后的代码会严格等待下载完成→打印日志→等待上传完成→返回响应,这样就能保证上传的是完整的文件了。
内容的提问来源于stack exchange,提问作者Scoop
相关产品推荐
相关产品推荐

