【发布时间】:2015-08-31 23:49:10
【问题描述】:
我正在使用 python 2.7.x 和 Boto API 2.X 连接到 AWS S3 存储桶。我有一个独特的情况,我想从 S3 存储桶下载文件到特定目录/文件夹,比如 myBucket/foo/。但问题是我想在 S3 文件夹中留下一个最新文件而不是下载它。有一次,我在本地机器上下载了这些文件,我想将这些文件移到同一存储桶下的不同文件夹中,例如 myBucket/foo/bar/。以前有没有人处理过类似的情况?
这里有一些解释:
- 将下载的文件从 S3 存储桶移动到同一存储桶下的不同文件夹路径。
我的 S3 存储桶:事件日志 S3 存储桶上的文件夹路径,将从中下载文件:
event-logs/apps/raw/source_data/
S3 存储桶上将移动下载文件的文件夹路径(存档):
event-logs/apps/raw/archive_data/
注意:“event-logs/apps/raw/”路径是上面同一个bucket下通用的
所以如果我在 S3 的 source_data 文件夹下有 5 个文件:
s3://event-logs/apps/raw/source_data/data1.gz
event-logs/apps/raw/source_data/data2.gz
event-logs/apps/raw/source_data/data3.gz
event-logs/apps/raw/source_data/data4.gz
event-logs/apps/raw/source_data/data5.gz
我需要将前 4 个文件(最旧的文件)下载到我的本地计算机并保留最新的文件,即data5.gz 后面。下载完成后,将这些文件从 S3 ../source_data 文件夹移动到同一 S3 存储桶下的 ../Archive_data 文件夹,并从原始 source_data 文件夹中删除。这是我列出 S3 中的文件的代码,然后下载文件,然后删除文件。
AwsLogShip = AwsLogShip(aws_access_key, aws_secret_access_key, use_ssl=True)
bucket = AwsLogShip.getFileNamesInBucket(aws_bucket)
def getFileNamesInBucket(self, aws_bucket):
if not self._bucketExists(aws_bucket):
self._printBucketNotFoundMessage(aws_bucket)
return list()
else:
bucket = self._aws_connection.get_bucket(aws_bucket)
return map(lambda aws_file_key: aws_file_key.name, bucket.list("apps/raw/source_data/"))
AwsLogShip.downloadAllFilesFromBucket(aws_bucket, local_download_directory)
def downloadFileFromBucket(self, aws_bucket, filename, local_download_directory):
if not self._bucketExists(aws_bucket):
self._printBucketNotFoundMessage(aws_bucket)
else:
bucket = self._aws_connection.get_bucket(aws_bucket)
for s3_file in bucket.list("apps/raw/source_data"):
if filename == s3_file.name:
self._downloadFile(s3_file, local_download_directory)
Break;
AwsLogShip.deleteAllFilesFromBucket(aws_bucket)
def deleteFilesInBucketWith(self, aws_bucket, filename):
if not self._bucketExists(aws_bucket):
self._printBucketNotFoundMessage(aws_bucket)
else:
bucket = self._aws_connection.get_bucket(aws_bucket)
for s3_file in filter(lambda fkey: filename(fkey.name), bucket.list("apps/raw/source_data/")):
self._deleteFile(bucket, s3_file)
我真正想在这里实现的是:
- 选择要下载的最旧文件列表,这意味着始终将最新修改的文件留在后面,不对它执行任何操作(因为该文件可能尚未准备好下载或仍在写入中)。
- 已下载的相同文件列表..需要移动到同一存储桶下的新位置,并从原始 source_data 文件夹中删除。
【问题讨论】:
-
您的要求很难理解。您能否提供一个示例(例如显示前后的内容)?
-
这个问题的答案可能会有所帮助 - stackoverflow.com/questions/30161700/…
-
@John Rotenstein - 根据您的要求,我已经用更多细节更新了这个问题。我可以请您对此发表专家意见吗?
-
是的,这一切都有可能,但这里有一个想法……为什么要跳过“最新”文件?如果它仍然“被写入”,它可能不会出现在您的对象列表中。它是由多个进程“写入”的吗?它会被覆盖吗?如果没有,它可能只会在完全创建后才会出现。这将大大简化您的要求,将其简化为大约 3 行:遍历列表、下载、移动。
-
这是另一种想法...一旦文件被下载,您打算如何处理它们——您是单独处理它们,还是只存储一个副本?如果只是为了保留副本,那么我建议使用AWS Command-Line Interface (CLI)
aws s3 sync命令将本地目录与存储桶同步。这样,您甚至不需要将文件移动到不同的目录,因为没有“处理”发生。您能否对您的用例提供更详细的说明,例如为什么需要以这种方式移动文件?
标签: python-2.7 amazon-web-services amazon-s3 boto