无法读取Google Cloud Storage视频,上传文件大小为0问题排查
排查Google Cloud Storage可恢复上传文件大小为0的问题
看起来你的代码在可恢复上传的流程上有几个潜在问题,导致文件实际没有被正确传输到GCS Bucket里,以下是具体的排查点和修正方案:
主要问题分析
- 重复调用
transmit_next_chunk:你在进入循环前先调用了一次transmit_next_chunk,这可能导致stream的读取位置异常,后续循环中无法读取剩余内容(甚至直接读取空数据)。 - 未明确传递文件长度:ResumableUpload依赖文件总长度来管理分块传输,如果没有明确提供,可能导致GCS无法正确接收完整数据。
- 未检查上传步骤的响应状态:代码中没有验证
initiate和transmit_next_chunk的执行结果,即使发生授权错误、网络问题也无法及时发现。 - 可能缺失正确的Content-Type:如果
content_type参数为空或不正确,可能导致GCS无法识别文件内容,最终存储空文件。
修正后的代码
url_template = ( u'https://www.googleapis.com/upload/storage/v1/b/{bucket}/o?' u'uploadType=resumable' ) upload_url = url_template.format(bucket=BUCKET_NAME) transport = AuthorizedSession(credentials=client._credentials) # 读取文件内容到BytesIO,同时获取文件总长度 stream_content = stream_file.file.read() stream = io.BytesIO(stream_content) content_length = len(stream_content) # 确保stream指针回到起始位置(BytesIO初始化后默认在开头,但显式重置更安全) stream.seek(0) # 确认content_type为正确的视频类型,比如video/mp4、video/mov等 content_type = "video/mp4" chunk_size = 10 * 1024 * 1024 # 设置合理的分块大小,比如10MB,可根据需求调整 upload = ResumableUpload(upload_url, chunk_size) metadata = {u'name': blob.name} # 初始化上传会话,检查响应是否成功 response = upload.initiate( transport, stream, metadata, content_type, content_length=content_length # 明确传递文件总长度 ) # 验证初始化是否成功,比如状态码为200或201 if response.status_code not in (200, 201): raise Exception(f"上传初始化失败: {response.text}") # 循环传输所有分块,直到完成 while not upload.finished: chunk_response = upload.transmit_next_chunk(transport) # 检查分块传输是否成功,308是可恢复上传的临时响应码,表示需要继续传输 if chunk_response.status_code not in (200, 201, 308): raise Exception(f"分块传输失败: {chunk_response.text}")
额外建议
- 确保
stream_file.file是一个可读的文件对象,且读取权限正常。 - 如果上传大文件,建议添加日志记录每个分块的传输状态,方便排查问题。
- 可以尝试先使用简单的上传方式(非可恢复)测试是否能正常上传文件,排除Bucket权限、网络连接等基础问题。
内容的提问来源于stack exchange,提问作者Dannick Montanede
相关产品推荐
相关产品推荐

