par*_*y72 7 tar amazon-s3 python-3.x boto3
在四处寻找想法时,我发现/sf/answers/3795571321/用于 zip 文件,我认为这是一个非常聪明的解决方案。但它依赖于具有中央目录的zip 文件- tar 文件没有。
我想我可以遵循相同的一般原则,并通过参数将 S3 文件公开给tarfilefileobj:
import boto3
import io
import tarfile
class S3File(io.BytesIO):
def __init__(self, bucket_name, key_name, s3client):
super().__init__()
self.bucket_name = bucket_name
self.key_name = key_name
self.s3client = s3client
self.offset = 0
def close(self):
return
def read(self, size):
print('read: offset = {}, size = {}'.format(self.offset, size))
start = self.offset
end = self.offset + size - 1
try:
s3_object = self.s3client.get_object(Bucket=self.bucket_name, Key=self.key_name, Range="bytes=%d-%d" % (start, end))
except:
return bytearray()
self.offset = self.offset + size
result = s3_object['Body'].read()
return result
def seek(self, offset, whence=0):
if whence == 0:
print('seek: offset {} -> {}'.format(self.offset, offset))
self.offset = offset
def tell(self):
return self.offset
s3file = S3File(bucket_name, file_name, s3client)
tarf = tarfile.open(fileobj=s3file)
names = tarf.getnames()
for name in names:
print(name)
Run Code Online (Sandbox Code Playgroud)
这工作正常,除了输出看起来像:
read: offset = 0, size = 2
read: offset = 2, size = 8
read: offset = 10, size = 8192
read: offset = 8202, size = 1235
read: offset = 9437, size = 1563
read: offset = 11000, size = 3286
read: offset = 14286, size = 519
read: offset = 14805, size = 625
read: offset = 15430, size = 1128
read: offset = 16558, size = 519
read: offset = 17077, size = 573
read: offset = 17650, size = 620
(continued)
Run Code Online (Sandbox Code Playgroud)
tarfile 无论如何都只是读取整个文件,所以我什么也没得到。有没有让 tarfile 只读取它需要的文件部分?我能想到的唯一替代方法是重新实现 tar 文件解析,因此它:
BytesIO缓冲区。BytesIO缓冲区。但这似乎过于复杂。
我的错。我实际上正在处理 tar.gz 文件,但我认为 zip 和 tar.gz 是相似的。它们不是 - tar 是一个存档文件,然后被压缩为 gzip,因此要读取 tar,您必须先将其解压缩。我从 tar 文件中提取位的想法行不通。
起作用的是:
s3_object = s3client.get_object(Bucket=bucket_name, Key=file_name)
wholefile = s3_object['Body'].read()
fileobj = io.BytesIO(wholefile)
tarf = tarfile.open(fileobj=fileobj)
names = tarf.getnames()
for name in names:
print(name)
Run Code Online (Sandbox Code Playgroud)
我怀疑原始代码适用于 tar 文件,但我没有任何代码可以尝试。
| 归档时间: |
|
| 查看次数: |
2038 次 |
| 最近记录: |