S3:如何在不下载完整文件的情况下进行部分读取/查找?
S3: How to do a partial read / seek without downloading the complete file?
虽然它们类似于文件,但 Amazon S3 中的对象并不是真正的 "files",就像 S3 存储桶不是真正的目录一样。在 Unix 系统上,我可以使用 head
来预览文件的前几行,无论它有多大,但我不能在 S3 上这样做。那么如何在 S3 上进行部分读取?
S3 文件可能很大,但您不必为了读取前几个字节而获取整个文件。 S3 API 支持 HTTP Range:
header (see RFC 2616),它采用字节范围参数。
只需将 Range: bytes=0-NN
header 添加到您的 S3 请求,其中 NN 是请求读取的字节数,您将只获取这些字节而不是读取整个文件。现在,您可以预览留在 S3 存储桶中的 900 GB CSV 文件,而无需等待整个文件下载完毕。阅读 the full GET Object
docs 亚马逊的开发者文档。
AWS .Net SDK 仅显示 fixed-ended 个范围是可能的(回复:public ByteRange(long start, long end)
)。如果我想从中间开始读到最后怎么办? Range: bytes=1000-
的 HTTP 范围对于 "start at 1000 and read to the end" 是完全可以接受的,我不相信他们在 .Net 库中允许这样做。
使用Python可以预览压缩文件的第一条记录。
使用 boto 连接。
#Connect:
s3 = boto.connect_s3()
bname='my_bucket'
self.bucket = s3.get_bucket(bname, validate=False)
从 gzip 压缩文件中读取前 20 行
#Read first 20 records
limit=20
k = Key(self.bucket)
k.key = 'my_file.gz'
k.open()
gzipped = GzipFile(None, 'rb', fileobj=k)
reader = csv.reader(io.TextIOWrapper(gzipped, newline="", encoding="utf-8"), delimiter='^')
for id,line in enumerate(reader):
if id>=int(limit): break
print(id, line)
所以它等同于以下 Unix 命令:
zcat my_file.gz|head -20
get_object api 有部分读取的 arg
s3 = boto3.client('s3')
resp = s3.get_object(Bucket=bucket, Key=key, Range='bytes={}-{}'.format(start_byte, stop_byte-1))
res = resp['Body'].read()
虽然它们类似于文件,但 Amazon S3 中的对象并不是真正的 "files",就像 S3 存储桶不是真正的目录一样。在 Unix 系统上,我可以使用 head
来预览文件的前几行,无论它有多大,但我不能在 S3 上这样做。那么如何在 S3 上进行部分读取?
S3 文件可能很大,但您不必为了读取前几个字节而获取整个文件。 S3 API 支持 HTTP Range:
header (see RFC 2616),它采用字节范围参数。
只需将 Range: bytes=0-NN
header 添加到您的 S3 请求,其中 NN 是请求读取的字节数,您将只获取这些字节而不是读取整个文件。现在,您可以预览留在 S3 存储桶中的 900 GB CSV 文件,而无需等待整个文件下载完毕。阅读 the full GET Object
docs 亚马逊的开发者文档。
AWS .Net SDK 仅显示 fixed-ended 个范围是可能的(回复:public ByteRange(long start, long end)
)。如果我想从中间开始读到最后怎么办? Range: bytes=1000-
的 HTTP 范围对于 "start at 1000 and read to the end" 是完全可以接受的,我不相信他们在 .Net 库中允许这样做。
使用Python可以预览压缩文件的第一条记录。
使用 boto 连接。
#Connect:
s3 = boto.connect_s3()
bname='my_bucket'
self.bucket = s3.get_bucket(bname, validate=False)
从 gzip 压缩文件中读取前 20 行
#Read first 20 records
limit=20
k = Key(self.bucket)
k.key = 'my_file.gz'
k.open()
gzipped = GzipFile(None, 'rb', fileobj=k)
reader = csv.reader(io.TextIOWrapper(gzipped, newline="", encoding="utf-8"), delimiter='^')
for id,line in enumerate(reader):
if id>=int(limit): break
print(id, line)
所以它等同于以下 Unix 命令:
zcat my_file.gz|head -20
get_object api 有部分读取的 arg
s3 = boto3.client('s3')
resp = s3.get_object(Bucket=bucket, Key=key, Range='bytes={}-{}'.format(start_byte, stop_byte-1))
res = resp['Body'].read()