如何解决Python直接传输S3文件到SMB共享时空文件的问题
问题原因
pysmb的storeFile方法要求传入的类文件对象必须支持seek()和tell()方法,用于提前获取待写入文件的总大小,符合SMB协议写入前的元数据声明要求。
而boto3的get_object返回的fileobj["Body"]是StreamingBody类型的流对象,仅支持顺序读取,没有实现seek()和tell()方法。pysmb内部读取文件大小失败时会默认按0字节处理,因此只会创建空文件,不会触发报错,也不会读取流中的实际内容。
解决方法
方案1:小文件场景(单文件大小不超过Lambda分配内存的1/2)
将StreamingBody整体读取后转为支持随机访问的BytesIO对象再传入,代码示例如下:
import io # 原有S3对象获取逻辑不变 fileobj = s3client.get_object( Bucket=bucketname, Key = file_to_read ) # 转换为支持seek/tell的BytesIO对象 seekable_obj = io.BytesIO(fileobj["Body"].read()) # 调用storeFile写入SMB connection.storeFile( service_name='s3-test', path='test-write.txt', file_obj = seekable_obj )
方案2:大文件场景
使用分块读取+逐段写入的方式,避免将整个文件加载到内存,代码示例如下:
import io # 可根据Lambda内存配置调整块大小,建议设置为5~10MB CHUNK_SIZE = 5 * 1024 * 1024 offset = 0 s3_body = fileobj["Body"] while True: chunk = s3_body.read(CHUNK_SIZE) if not chunk: break # 逐块写入SMB共享 connection.storeFileFromOffset( service_name='s3-test', path='test-write.txt', file_obj=io.BytesIO(chunk), offset=offset ) offset += len(chunk)
内容的提问来源于stack exchange,提问作者SimonCox
相关产品推荐
相关产品推荐

