我正在尝试将 Google Cloud Storage 对象下载到运行 Node.js 的 Google Cloud Run 服务中的
/tmp
。我遵循了本教程并有以下代码:
exports.resizeImage = async (eventData) => {
const file = storage.bucket(eventData.bucket).file(eventData.name);
// Resolve the image extension
const [metadata] = await file.getMetadata();
const extension = metadataContentTypeToExtension(metadata.contentType);
const tempLocalPath = `/tmp/${path.parse(file.name).base}.${extension}`;
console.log(tempLocalPath); // Prints "/tmp/clpeytui4003nfcsjqjyifk0d.jpg"
try {
// This is just for testing to see if I'm pointing at the object correctly
const url = await file.getSignedUrl({
action: 'read',
expires: '03-17-2025',
});
console.log(`Here's an access URL: ${url}`);
} catch (err) {
console.error('Unable to get presigned URL:');
console.error(err);
}
// Download file from bucket.
try {
console.log(`Downloading ${file.name} to ${tempLocalPath}...`);
const dlPromise = file.download({ destination: tempLocalPath });
dlPromise.catch((err) => {
console.error('Download failed (caught in promise catch).');
console.error(err);
});
} catch (err) {
console.error(`File download failed: ${err}`);
return;
}
如果我将预签名 URL 复制并粘贴到浏览器中,它就可以工作,所以我很确定我正确定位了该文件。我还为该服务授予了
storage.admin
角色(因为它抱怨无法在某一时刻列出存储桶内容),所以我 认为 我已经授予了它所需的权限...
据我所知,服务/代码似乎无法获取数据流来下载文件,但我不确定这是否是问题所在。我尝试指定自己的下载函数,看看是否是 GCS 库错误:
const downloadFile = (file, downloadPath) =>
new Promise((resolve, reject) => {
console.log('Attempting to download file...');
file
.createReadStream()
.pipe(fs.createWriteStream(downloadPath))
.on('finish', () => {
console.log(`Image downloaded locally to ${downloadPath}`);
console.log(`File size: ${fs.statSync(downloadPath).size} bytes`);
resolve();
})
.on('error', (err) => {
console.error('Failed to download file.', err);
reject(err);
});
});
但是我在同一个底层
stream-shift
调用中遇到了相同的错误,所以我猜这正是 Node 使用的。
奇怪的是我在任何地方都没有看到任何自定义错误消息......
关于可能出什么问题或者我下一步应该尝试什么有什么想法吗?
访问未定义值的 length 属性时,会发生“TypeError:无法读取未定义的属性(读取‘length’)”错误。要解决此错误,请确保仅访问支持它的数据类型(数组和字符串)的 length 属性。在访问 length 之前检查值的类型是否正确。
您还可以在访问 length 属性之前检查值的类型是否正确。
//Check if array before accessing length if (Array.isArray(value)) { const result = value.length; console.log(result); } else { console.log('The value is NOT an array'); }
// Check if string before accessing length if (typeof value === 'string') { const result = value.length; console.log(result); } else { console.log('The value is NOT a string'); }
查看此有用的官方文档以了解流式下载。
另请检查这些链接,其中讨论了类似的实现: