Python S3.Client.upload_file()和S3.Client.upload_fileobj()之间有什么区别?
根据和,Python S3.Client.upload_file()和S3.Client.upload_fileobj()之间有什么区别?,python,python-3.x,amazon-web-services,amazon-s3,boto3,Python,Python 3.x,Amazon Web Services,Amazon S3,Boto3,根据和,upload\u fileobj可能听起来更快。但有人知道具体情况吗?我应该只上传文件,还是以二进制模式打开文件以使用upload\u fileobj?换句话说, import boto3 s3 = boto3.resource('s3') ### Version 1 s3.meta.client.upload_file('/tmp/hello.txt', 'mybucket', 'hello.txt') ### Version 2 with open('/tmp/hello.tx
upload\u fileobj
可能听起来更快。但有人知道具体情况吗?我应该只上传文件,还是以二进制模式打开文件以使用upload\u fileobj
?换句话说,
import boto3
s3 = boto3.resource('s3')
### Version 1
s3.meta.client.upload_file('/tmp/hello.txt', 'mybucket', 'hello.txt')
### Version 2
with open('/tmp/hello.txt', 'rb') as data:
s3.upload_fileobj(data, 'mybucket', 'hello.txt')
版本1还是版本2更好?有区别吗?两者都不好,因为它们不可比。虽然最终结果是相同的(一个对象被上传到S3),但它们对该对象的来源却完全不同。一个期望您提供要上载的文件在磁盘上的路径,而另一个期望您提供类似文件的对象 如果您在磁盘上有一个文件,并且想要上传它,那么使用
upload\u file
。如果您有一个类似文件的对象(最终可能是很多东西,包括打开的文件、流、套接字、缓冲区、字符串),那么使用upload\u fileobj
在此上下文中,“类文件对象”是实现read
方法并返回字节的任何对象。TL;博士
就速度而言,两种方法的性能大致相同,都是用python编写的,瓶颈是磁盘io(从磁盘读取文件)或网络io(写入s3)
- 编写仅处理从磁盘上载文件的代码时,请使用
upload\u file()
- 当您编写处理s3上传的通用代码时,请使用
,这些代码将来可能会被重用,而不仅仅用于磁盘文件用例upload\u fileobj()
fileobj到底是什么? 在包括python标准库在内的多个地方都有一个惯例,即当使用术语
fileobj
时,她的意思是。
甚至有些库公开的函数可以将文件路径(str)或fileobj(类似文件的对象)作为相同的参数
使用文件对象时,您的代码不仅限于磁盘,例如:
import gzip, io
def gzip_greet_file(fileobj):
"""write gzipped hello message to a file"""
with gzip.open(filename=fileobj, mode='wb') as fp:
fp.write(b'hello!')
# using opened file
gzip_greet_file(open('/tmp/a.gz', 'wb'))
# using filename from disk
gzip_greet_file('/tmp/b.gz')
# using io buffer
file = io.BytesIO()
gzip_greet_file(file)
file.seek(0)
print(file.getvalue())
另一方面,有两个参数file&fileobj:
tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)
使用
s3.upload\u fileobj()
upload_fileobj的要点是,文件对象首先不必存储在本地磁盘上,但可以在RAM中表示为文件对象 Python为此目的提供了一些支持 代码如下所示
import io
fo = io.BytesIO(b'my data stored as file object in RAM')
s3.upload_fileobj(fo, 'mybucket', 'hello.txt')
在这种情况下,它将执行得更快,因为您不必从本地磁盘读取数据。如中的文档所示 upload_file和upload_fileobj方法由S3客户端、Bucket和对象类提供。每个类提供的方法功能相同。调用一个类的方法而不是另一个类的方法不会获得任何好处。请使用最方便的类
上面的答案似乎是错误的我的使用涉及csv文件,因此由于python
csv
库不能很好地处理字节,我想我应该只使用s3。为了方便起见,上传文件
。上面的示例可以与字节和str一起使用,只要正确地更改模式即可。顺便说一句,csv模块接受文件对象,因此无论哪种方式,您都应该手动打开文件。在任何情况下,实现的好运气似乎表明在Python3
中使用csv
很麻烦。csv到底有什么麻烦?线程上的第一个答案似乎对OP有所帮助。在python中如何处理csv?如果您有关于csv处理的更多问题,您可能希望打开另一个问题,以便我们可以帮助您。上述答案并非100%正确。请参考相同的源代码状态:upload\u file方法接受文件名、bucket名和对象名。该方法通过将大型文件拆分为较小的块并并行上载每个块来处理大型文件。
和上载\u fileobj方法接受一个可读的类似文件的对象。文件对象必须以二进制模式打开,而不是以文本模式打开。
上面回答了这个问题。
import io
fo = io.BytesIO(b'my data stored as file object in RAM')
s3.upload_fileobj(fo, 'mybucket', 'hello.txt')