如何在Node.js环境下分块上传大文件至Google Bucket
报错根因
你遇到的Cannot create a string longer than 0x1fffffe8 characters报错是Node.js运行时对单个连续内存分配的字符串/Buffer有固定上限,你当前使用的两种上传方式默认会将完整文件加载到内存后再提交,超过阈值就会触发该限制。
推荐解决方案:使用Google Cloud Storage SDK自带分块上传
不需要手动拆分合并文件,官方@google-cloud/storageSDK原生支持可恢复分块上传,会自动处理分块、断点续传、合并逻辑,不会将完整文件加载到内存,可完美规避该报错。
1. 常规upload方法修复
新增分块上传相关配置即可:
await storage.bucket(BUCKET) .upload(file.path, { destination: file.name, // 核心配置项 resumable: true, // 开启可恢复分块上传 chunkSize: 10 * 1024 * 1024, // 单块大小设置为10MB,可根据网络情况调整,建议为10MB的整数倍 })
2. 流式上传修复
你之前的流式写法存在适配问题,替换为SDK提供的createWriteStream方式即可:
const bucket = storage.bucket(BUCKET); const gcsTargetFile = bucket.file(file.name); const fileSize = file.size; fs.createReadStream(file.path) .pipe(gcsTargetFile.createWriteStream({ resumable: true, chunkSize: 10 * 1024 * 1024, })) .on("progress", (progress) => { console.log("Progress event:"); console.log("\t bytes: ", progress.bytesWritten); const pct = Math.round((progress.bytesWritten / fileSize) * 100); console.log(`\t ${pct}%`); }) .on("finish", () => { console.log("Upload complete!"); resolve(); }) .on("error", (err) => { console.error("There was a problem uploading the file"); reject(err); });
可选方案:手动分块上传后合并
如果你确实需要自己实现分块逻辑,可使用GCS的复合对象能力实现:
- 将本地文件按固定大小切分为多个临时块,单块建议不小于10MB,最后一块可小于10MB
- 按顺序上传所有块到存储桶,命名使用带唯一标识和序号的规则,避免和其他文件块冲突
- 所有块上传完成后调用
combine接口合并为完整文件 - 合并完成后删除所有临时块
示例代码:
// chunks为按顺序排列的所有临时块对应的GCS File对象 const chunks = [bucket.file('temp_chunk_xxx_0'), bucket.file('temp_chunk_xxx_1'), /* 其余块 */]; const targetFile = bucket.file(file.name); // 合并块 await targetFile.combine(chunks); // 删除临时块 await Promise.all(chunks.map(chunk => chunk.delete()));
注意事项
- 单次
combine最多支持合并32个块,如果拆分块数超过32需要分层合并 - 必须按文件的正确顺序传入块列表,否则合并出的文件会损坏
内容的提问来源于stack exchange,提问作者wowza_MAN
相关产品推荐
相关产品推荐

