功能丰富的 Perl: Amazon S3 上的储存管理--用于管理 S3 bucket 及其内容的 3 个 CPAN

了解 Perl 程序员如何使用 3 个 CPAN S3 模块 —— Net::Amazon::S3、Amazon::S3 和 SOAP::Amazon::S3 —— 来列出、创建和删除 bucket(S3 数据储存);列出、创建、获取和删除 bucket 中的项;以及获得一个项的元数据。

Perl 开发人员拥有一个出色的资源,即 Comprehensive Perl Archive Network (CPAN)。Amazon 也有一个出色的资源 Simple Storage Service (S3)。尽管在 CPAN 上存在一个官方的 Amazon S3 Perl 库(称为 S3),但是 S3 涉及到至少 5 个或 6 个模块(不过有些不是完全独立的)。这好像一场辣椒烹饪比赛,出场的不是 200 人,而是 2000 人。

现在,我在比赛结束后的一天出现了,和您分享最佳的烹饪秘诀。这些模块和工具在 CPAN 上免费提供,您可以立即使用它们。我推荐 3 个属于这三个模块的秘方:Net::Amazon::S3、Amazon::S3 和 SOAP::Amazon::S3。

从 developerWorks 上的 功能丰富的 Perl:Perl 和 Amazon 云 系列阅读关于 S3 的优点和缺点的讨论。没有必要在这里重复讨论,不过我会简单总结一下。

S3 是由 Amazon 提供和管理的储存服务。Amazon 对用户的访问收费,因此不用担心服务器、备份、带宽可用性和分布等。因此,S3 和日常生活中的许多物品一样,是廉价便利的,并且由您决定它是否适合您的业务或个人需求。

S3 数据和 bucket 中的数据项通过 bucket(与域名大致相似)组织起来。提醒一下,在上传时一定要保护 MIME 类型,否则您将下载到原始的二进制数据(这对映像的影响尤其大)。MIME 类型和其他元数据在写入之后就不能再更改 —— 您必须删除并重新创建该项。

在深入探索之前声明一下,本文针对具有中等水平的 Perl 程序员。本文不详细解释基础的 Perl 技术。此外,您应该知道什么是 S3 以及如何安装 CPAN 模块。

本文的目标

我借助 3 个模块(Net::Amazon::S3、Amazon::S3 和 SOAP::Amazon::S3)解释如何执行一系列基础的 S3 操作,并展示必要的源代码,如下所示:

列出、创建和删除 bucket 列出、创建、获取和删除 bucket 中的项 获取项的元数据

为了让这些任务在模块之间具有可比性,我重用了相同的命令行选项和总体结构。

Net::Amazon::S3

了解 Moose

Moose 的主要目标是让 Perl 5 OOP 更加易于使用、更加一致,从而减轻程序员的压力。通过帮助您 “放开” 面向对象编程的机制,Moose 帮助您关注您想实现的目标。构建在 Class::MOP 之上的 Moose 也使得元类编程更加容易。如果您还没有尝试过这些特性,那么应该尝试一下;它是用 Perl 处理 OOP 的出色方式。

Net::Amazon::S3 模块是一个著名的模块,它受到广泛的支持,功能也很全面。它有一些前提条件,但要比 Moose 合理得多(如果您了解的话)。

我们将把 S3 密匙作为 S3KEY 和 S3SECRET 储存在环境中。 这样,我们就可以通过 Perl 以 $ENV{S3KEY} 和 $ENV{S3SECRET} 的形式访问它们。这种在文件中储存数据的方法是一种比较安全的保护隐私性的方法(记住,如果 S3 密匙被盗,您将为他人购买带宽)。

现在,Net::Amazon::S3 已经安装完毕。(您最好使用推荐的 Net::Amazon::S3::Client 接口,因为 Net::Amazon::S3 被称为 “旧有接口”。但是 Net::Amazon::S3::Client version 0.50 由于 Moose 模块而存在一个 bug,因此我在撰写本文时不能使用它。这个 bug 在 version 0.51 已经修复,当前的版本是 0.52)。现在让我们探索例子。和以往一样,下载 小节提供所有脚本。

清单 1. net-amazon-s3.pl 准备

#!/usr/bin/perluse warnings;use strict;use Data::Dumper;use Getopt::Long;use Net::Amazon::S3;use MIME::Types;my $mime = MIME::Types->new();

这是标准的代码,包括用于调试目的的 Data::Dumper。这里创建了一个泛型的 MIME 对象,尽管我们仅在上传时使用它。

清单 2. net-amazon-s3.pl 选项、帮助函数和初始 S3 连接

my %opts = ( key => $ENV{S3KEY}, secret => $ENV{S3SECRET}, separator => '/', );GetOptions( \%opts, "create|c=s", "delete|d=s", "list|l:s", # the parameter is optional "keys|k", "metadata|m", "get=s", "put=s", "separator=s", "help|h", );unless ($opts{key} && $opts{secret} ){ die "$0 requires the S3KEY and S3SECRET environment variables to be set.";}# handle -husage() if exists $opts{help};my $s3 = Net::Amazon::S3->new( aws_access_key_id => $opts{key}, aws_secret_access_key => $opts{secret}, retry => 1, );die "Could not connect to S3" unless defined $s3;sub read_filename{ print "\nEnter filename: "; my $name = <>; chomp $name; return $name;}sub usage{ print lt;<EOHIPPUS; $0 [OPTIONS]Pass your S3 key and secret in the S3KEY and S3SECRET environment entries.Options: --help or -h : this help --separator $opts{separator} : BUCKET and KEY separator character (for --get and --put) --create BUCKET (or -c BUCKET) : create BUCKET --delete BUCKET (or -d BUCKET) : delete BUCKET --delete BUCKET$opts{separator}KEY : delete KEY in BUCKET --list [BUCKET] (or -l) : list a specific bucket or all buckets --keys (or -k) : list the keys in each bucket (requires --list) --metadata (or -m) : show the keys' metadata (requires --keys and --list) --get BUCKET$opts{separator}KEY : download KEY from BUCKET --put BUCKET$opts{separator}KEY : upload a file to KEY in BUCKETEOHIPPUS exit 0;}

这是更加标准的代码。选项是在这里设置的。usage() 函数非常全面,这让程序更加有用。列出并简单解释了每个选项。

清单 3. net-amazon-s3.pl 创建和删除操作

if (exists $opts{create}) { my $bucket = $s3->add_bucket( { bucket => $opts{create}} ) or die sprintf ("%s: %s", $s3->err, $s3->errstr); print "Created bucket '$opts{create}' successfully.\n";}elsif (exists $opts{delete}) { my ($b, $key) = split $opts{separator}, $opts{delete}; my $bucket = $s3->bucket($b); die "Could not retrieve bucket $b" unless $bucket; if (defined $key) { $bucket->delete_key($key) or die sprintf ("%s: %s", $s3->err, $s3->errstr); print "Deleted key '$key' in bucket '$b' successfully.\n"; } else { $bucket->delete_bucket() or die sprintf ("%s: %s", $s3->err, $s3->errstr); print "Deleted bucket '$b' successfully.\n"; }}

--create 选项非常简单。您仅需创建 bucket 并返回。

对于 --delete,它处理 bucket 删除(非递归的,因此用户必须先删除 bucket 中的所有密匙)或 bucket 中的密匙删除。在这里,分隔符作为 bucket 名和密匙名的分隔点。

清单 4. net-amazon-s3.pl 的 get 和 put 操作

...elsif (exists $opts{get}){ my ($b, $key) = split $opts{separator}, $opts{get}; my $bucket = $s3->bucket($b); die "Could not get the bucket $b" unless $bucket; my $where = read_filename(); my $response = $bucket->get_key_filename( $key, 'GET', $where ) or die sprintf ("%s: %s", $s3->err, $s3->errstr); die "Could not create file $where" unless -f $where; print "Successfully downloaded $key from bucket $b into $where\n";}elsif (exists $opts{put}){ my ($b, $key) = split $opts{separator}, $opts{put}; my $bucket = $s3->bucket($b); die "Could not get the bucket $b" unless $bucket; my $where = read_filename(); die "File $where does not exist or is not readable" unless -f $where && -r $where; my $response = $bucket->add_key_filename( $key, $where, { content_type => $mime->mimeTypeOf($where), }, ) or die sprintf ("%s: %s", $s3->err, $s3->errstr); print "Successfully uploaded $where into $key in bucket $b\n";}

Get 和 put 非常相似,它们都是在文件名和密匙名上操作的。在这里,最有趣的是 MIME::Types $mime 对象,我们使用它来获取内容的类型。记住,在上传之后就不能再更改它。

清单 5. net-amazon-s3.pl 的 list 操作

...elsif (exists $opts{list}){ print "Available buckets:\n"; my @todo; if ($opts{list}) { push @todo, map { $s3->bucket($_) } $opts{list}; } else { print "(Getting all buckets)\n"; my $response = $s3->buckets; die "Could not get the bucket list" unless $response; @todo = @{$response->{buckets}}; } foreach my $bucket ( @todo ) { printf "\t%s\n", $bucket->bucket; if (exists $opts{keys}) { my $response = $bucket->list_all or die sprintf ("%s: %s", $s3->err, $s3->errstr); foreach my $key (@{$response->{keys}}) { printf "\t\t%10s\t%s\n", $key->{size}, $key->{key}; if (exists $opts{metadata}) { my $detail = $bucket->get_key($key->{key}); foreach my $entry (qw/content_length content_type etag/) { printf "\t\t\t%20s=%s\n", $entry, ($detail->{$entry}||'UNDEFINED'); } } } } }}

最后并且也是最长的是 --list 事件处理程序,它将处理一个或多个 bucket。它将显示密匙及其元数据的列表。

\t 字符被转换成制表符;它的作用是为输出提供粗略的缩进,让它在文本中具有更好的格式。

如您所见,Net::Amazon::S3 是一个非常干净的模块。其中的一部分方法有点奇怪,但它们能够出色地工作。在获取项和将它们与元数据一起使用之间存在一个断点,这需要用到一个额外的 get_key() 调用。该模块的所有代码都是简短的。

Amazon::S3

Amazon::S3 模块是 Net::Amazon::S3 的替换。我必须更改 new() 调用以使用散列引用,不过这也是唯一需要更改的地方(很明显,还要将所有 Net::Amazon::S3 引用更改为 Amazon::S3)。

清单 6. 从 net-amazon-s3.pl 更改而来的 amazon-s3.pl

my $s3 = Amazon::S3->new({ aws_access_key_id => $opts{key}, aws_secret_access_key => $opts{secret}, retry => 1, });

Amazon::S3 支持许多选项;请参考文档看看是否可以使用它们。一般而言,Amazon::S3 的目标好像与 Net::Amazon::S3 稍有不同,但是从开发人员的角度看,它们的 API 是相同的。这对库的互操作性非常有益。

您可能很欣赏 Amazon::S3 的一个特性,即它不像 Net::Amazon::S3 那样依赖许多模块。他的开发者还强调它是可移植的,这对需要它的人而言是件好事。

SOAP::Amazon::S3

探索 File::Slurp

File::Slurp 模块提供的代替项允许您仅使用一个简单的调用来读或写整个文件。它们的目标是简单易用,以及能够灵活地传入或获取文件内容。除了 . 和 .. 之外,还有一个代替项可以读取一个目录下的所有文件。这些代替项适用于文件、管道、套接字、stdio、伪文件和 DATA。

学习 SOAP::Amazon::S3 模块需要了解一些背景知识,我将针对本文稍作介绍。SOAP 是通过 HTTP(Web)访问信息的一种方式,它与使用路径表示资源的常见 HTTP 请求不同。这些请求通常被称为是 REST 式的,并且趋向于发展成许多 URL 变体;相反,SOAP 仅命中一小部分 URL,并且将所有 XML 传递给服务器。

我很希望能够继续谈 SOAP,但这是一个非常广泛的主题,因此我把它留给读者去探索。对于其价值,SOAP 和 REST 的差别并不是很大。您使用哪种方法都可以编写出出色或糟糕的代码。

不幸的是,SOAP::Amazon::S3 在文档中被标记为处于试验阶段。您应该亲自测试它,看看是否适合您。

谈论区别。首先,我们需要 File::Slurp 模块,因为 SOAP::Amazon::S3 不能像 Net::Amazon::S3 和 Amazon::S3 那样提供上传和下载文件的便利方法。

清单 7. soap-amazon-s3.pl 准备

# set Debug to 0 if you don't want to see all the XMLmy $s3 = SOAP::Amazon::S3->new( $opts{key}, $opts{secret}, { Debug => 1, RaiseError => 1 } );

我忽略了 Debug=1,因为您将怀着好奇心查看 SOAP::Amazon::S3 生成的所有 SOAP 流量。由于 RaiseError=1,所以我对 Net::Amazon::S3 进行的所有错误检查都是不必要的,但这在生产环境中不是好主意。

创建 bucket (my $bucket = $s3->createbucket($opts{create});) 与使用 Net::Amazon::S3 创建 bucket 不同,因为它删除一个 bucket ($bucket->delete()) 或一个对象 ($bucket->object($key)->delete();)。

将数据写到一个文件稍微复杂些,因为如前所述,SOAP::Amazon::S3 不具备 Net::Amazon::S3 中的便利函数。

清单 8. soap-amazon-s3.pl 写文件

open W, '>', $where or die "Could not write to $where: $!";print W $bucket->object($key)->getdata();close W;

从文件上传也一样要复杂些。

清单 9. soap-amazon-s3.pl 上传文件

my $type = ''.$mime->mimeTypeOf($where); # force $type to be a string # use File::Slurp::read_file in scalar context to grab the whole file's contents my $data = read_file($where); $bucket->putobject($key, $data, { 'Content-Type' => $type });

MIME 类型必须装在一个字符串中,否则将影响 XML 帮助函数模块。此外,内容类型的大写化也与 Net::Amazon::S3 不同。

最后,我们讨论列出项。在这里,SOAP::Amazon::S3 不像 Net::Amazon::S3 那样强大,因为对象元数据不可用。SOAP::Amazon::S3 有一个出色的 $object->url() 方法,但它没有将空间转换成 %20,因此您要试用它,看看是否适合您。我提交了一个 bug(记住,这还是一个实验模型),但是现在我避开了生产环境中的 $object->url() 方法。

清单 10. soap-amazon-s3.pl 列出 bucket 和其中的对象

...elsif (exists $opts{list}){ print "Available buckets:\n"; my @todo; if ($opts{list}) { push @todo, map { $s3->bucket($_) } $opts{list}; } else { print "(Getting all buckets)\n"; @todo = $s3->listbuckets; } foreach my $bucket ( @todo ) { printf "\t%s\n", $bucket->name; if (exists $opts{keys}) { foreach my $key ($bucket->list()) { printf "\t\t%10s\t%-30s\t%s\n", $key->{Size}, $key->name, $key->url; if (exists $opts{metadata}) { foreach my $entry (qw/Size ETag LastModified/) { printf "\t\t\t%20s=%s\n", $entry, ($key->{$entry}||'UNDEFINED'); } } } } }}

如您所见,SOAP::Amazon::S3 没有获取元数据,因此您不能看到对象的内容类型等。如果您使用元数据来储存关于对象的重要信息时,这是一个令人不愉快的限制。如果不存在该限制的话,SOAP::Amazon::S3 在列出 bucket 及其元素方面可以与 Net::Amazon::S3 媲美。

结束语

我没有详细评估另外两个 S3 CPAN 模块,而是在这里简要概括一下:

如果您想要通过命令行访问 S3,Net::Amazon::S3::Tools 是不错的选择。这比自己编写好,因此您可以使用现成的工具测试它。 如果仅处理单个 bucket,Tie::Amazon::S3 是不错的模块。您可以删除或修改散列条目和添加新的条目等等。不幸的是,它不允许 bucket 级别的操作(创建 bucket 和删除 bucket 等)或元数据操作(尤其是在新的密匙上设置内容类型)。因此,如果您想要在 S3 中储存纯数据,Tie::Amazon::S3 是非常有用的,但它对映像的用途不大。

总体而言,Net::Amazon::S3 和 Amazon::S3 目前是处理 S3 的最佳选择。它们的互操作性 API 能够在必要时进行切换。它们支持所有操作,上至 bucket 操作,下至元数据获取。它们的 API 有些奇怪,但在设置之后很容易使用。

关注一下 SOAP::Amazon::S3,它很有潜力。如果您在单个 bucket 中处理纯数据,那么最好使用 Tie::Amazon::S3,因为它能够提供很多方便。

祝您使用 S3 愉快!

样例脚本,amazon-s3-scripts.zip:temp_10030722337598.zip

时间: 2024-10-25 19:59:06

功能丰富的 Perl: Amazon S3 上的储存管理--用于管理 S3 bucket 及其内容的 3 个 CPAN的相关文章

功能丰富的 Perl: Perl 和 Amazon 云,第 3 部分--上传图像并创建、编辑和删除评论

这个共分 5 部分的系列文章向您介绍了如何使用 Perl 和 Apache 访问 Amazon 的 Simple Storage Service (S3) 和 SimpleDB,从而构建一个照片共享网站.在本期文章中,通过学习 URL 如何为上传的文件创建 SimpleDB 记录,实现站点与 SimpleDB 的交互.同时了解如何以 SimpleDB 记录的形式创建.编辑.删除某个用户的照片评论. 距离我的上一期文章已经有一段时间了,现在我们来回顾一下: 第 1 部分解释了 S3/SimpleD

功能丰富的 Perl: Perl 和 Amazon 云,第 1 部分--通过构建简单的照片共享网站学习 Amazon S3 和 SimpleDB 服务的基础知识

在这个 5 部分系列文章的第 1 部分中,Ted Zlatanov 解释了 Amazon 的 Simple Storage Service (S3) 和 SimpleDB 产品在构建 Web 站点方面的优势和不足.这个系列通过实际示例形象地介绍了 S3 和 SimpleDB 架构以及如何使用它们:在本文中,将使用 Perl 库构建一个简单的照片共享网站. 您需要学习 Amazon 的两个 Web 服务:Amazon S3 (Simple Storage Service) 和 Amazon Sim

功能丰富的 Perl: Perl 和 Amazon 云,第 2 部分--通过 HTML 表单将数据安全地上传到 S3

这个共5个部分的系列文章将带领您使用 Perl 和 Apache 构建一个简单的照片共享网站,访问 Amazon 的 Simple Storage Service (S3) 和 SimpleDB.在这一期文章中,理解如何通过一个 HTML 表单将一个文件从 Web 页面上传到 S3,最小化服务上的负载,同时维护严格的安全策略. 您可以通过多种方式将文件从一个 Web 页面上传到 Amazon 的 Simple Storage Service (S3): 使用来自 CPAN 的合适的模块从命令行上

功能丰富的 Perl: Perl 和 Amazon 云,第 4 部分--深入探究完整 mod_perl 站点的代码库

这个共分 5 部分的系列文章向您介绍了如何使用 Perl 和 Apache 构建一个照片共享网站,从而访问 Amazon 的 Simple Storage Service (S3) 和 SimpleDB.在本期文章中,研究完整 mod_perl 站点的代码库,包括如何设置顶级配置.如何使用处理程序,以及如何设置外部依赖关系. 在本期文章中,我们将研究完整的 mod_perl 站点(只讨论代码:模板在下期文章讨论).前几期文章中,我们的节奏有些缓慢,现在,通过研究 mod_perl,我们将加快步伐

功能丰富的 Perl: Perl 和 Amazon 云,第 5 部分--了解完整 mod_perl 站点的模板

这个共分 5 部分的系列文章向您介绍了如何使用 Perl 和 Apache 构建一个照片共享网站,从而访问 Amazon 的 Simple Storage Service (S3) 和 SimpleDB.在这最后一期文章中,我们将考察完整 mod_perl 站点的模板,包括一个用于索引的模板.三个用于上传的模板(通用模板.S3 表单和 URL 添加物).一个用于浏览照片和评论的模板,以及一个用于递归式地浏览(即遍历浏览)照片评论的模板. 在最后一期文章中,我们将了解完整的 mod_perl 站点

在Amazon EC2上运行Spark

在Amazon EC2上运行Spark Spark的ec2目录下有一个spark-ec2脚本,可以帮助你在Amazon EC2上启动.管理.关闭Spark集群.该脚本能在EC2集群上自动设置好Spark和HDFS.本文将会详细描述如何利用spark-ec2脚本来启动和关闭集群,以及如何在集群提交作业.当然,首先你必须在Amazon Web Services site上注册一个EC2的账户.   spark-ec2可以管理多个命名集群.你可以用它来启动一个新集群(需要提供集群大小和集群名称),关闭

《Spark 官方文档》在Amazon EC2上运行Spark

在Amazon EC2上运行Spark Spark的ec2目录下有一个spark-ec2脚本,可以帮助你在Amazon EC2上启动.管理.关闭Spark集群.该脚本能在EC2集群上自动设置好Spark和HDFS.本文将会详细描述如何利用spark-ec2脚本来启动和关闭集群,以及如何在集群提交作业.当然,首先你必须在Amazon Web Services site上注册一个EC2的账户.   spark-ec2可以管理多个命名集群.你可以用它来启动一个新集群(需要提供集群大小和集群名称),关闭

php根据isbn书号查询amazon网站上的图书信息的示例

 这篇文章主要介绍了php根据isbn书号查询amazon网站上的图书信息的示例,需要的朋友可以参考下 插件说明: 插件根据提供的10位ISBN书号,在Amazon网站上查找该图书的详细信息. 如果找到结果,则返回一个两元素的数组,其中第一个元素是书的标题,而第二个元素是该书封面缩写图的URL地址. 它需要以下参数:$ISBN 10位ISBN书号    代码如下: $isbn   = '007149216X'; $result = PIPHP_GetBookFromISBN($isbn); if

wm-我想实现qq群发的功能,就是说把粘贴板上的内天发给好友,然后关闭好友对话框,求老司机指路

问题描述 我想实现qq群发的功能,就是说把粘贴板上的内天发给好友,然后关闭好友对话框,求老司机指路 // PostMsgDemo.cpp: 定义控制台应用程序的入口点 // #include"stdafx.h" #include BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM param) { char strClassName[MAXBYTE] = { 0 }; GetClassNameA(hWnd, strClassName, MAX