Class: Aliyun::OSS::Bucket

Inherits:
Struct::Base show all
Defined in:
lib/aliyun/oss/bucket.rb

Overview

Bucket是用户的Object相关的操作的client,主要包括三部分功能:

  1. bucket相关:获取/设置bucket的属性(acl, logging, referer, website, lifecycle, cors)

  2. object相关:上传、下载、追加、拷贝object等

  3. multipart相关:断点续传、断点续载

Instance Method Summary collapse

Methods inherited from Struct::Base

#to_s

Methods included from Struct::Base::AttrHelper

#attrs

Constructor Details

#initialize(opts = {}, protocol = nil) ⇒ Bucket

Returns a new instance of Bucket.



15
16
17
18
# File 'lib/aliyun/oss/bucket.rb', line 15

def initialize(opts = {}, protocol = nil)
  super(opts)
  @protocol = protocol
end

Instance Method Details

#access_key_idString

获取用户所设置的ACCESS_KEY_ID

Returns:

  • (String)

    用户的ACCESS_KEY_ID



525
526
527
# File 'lib/aliyun/oss/bucket.rb', line 525

def access_key_id
  @protocol.get_access_key_id
end

#aclString

获取Bucket的ACL

Returns:



24
25
26
# File 'lib/aliyun/oss/bucket.rb', line 24

def acl
  @protocol.get_bucket_acl(name)
end

#acl=(acl) ⇒ Object

设置Bucket的ACL

Parameters:



30
31
32
# File 'lib/aliyun/oss/bucket.rb', line 30

def acl=(acl)
  @protocol.put_bucket_acl(name, acl)
end

#append_object(key, pos, opts = {}) {|HTTP::StreamWriter| ... } ⇒ Integer

向Bucket中的object追加内容。如果object不存在,则创建一个 Appendable Object。

Examples:

流式上传数据

pos = append_object('x', 0){ |stream| 100.times { |i| stream << i.to_s } }
append_object('x', pos){ |stream| stream << get_data }

上传文件

append_object('x', 0, :file => '/tmp/x')

指定Content-Type和metas

append_object('x', 0, :file => '/tmp/x', :content_type => 'text/html',
              :metas => {'year' => '2015', 'people' => 'mary'})

Parameters:

  • key (String)

    Object的名字

  • opts (Hash) (defaults to: {})

    上传object时的选项(可选)

Options Hash (opts):

  • :file (String)

    指定追加的内容从文件中读取

  • :content_type (String)

    设置所上传的内容的 Content-Type,默认是application/octet-stream

  • :metas (Hash)

    设置object的meta,这是一些用户自定 义的属性,它们会和object一起存储,在#get_object的时候会 返回这些meta。属性的key不区分大小写。例如:{ ‘year’ => ‘2015’ }

Yields:

Returns:

  • (Integer)

    返回下次append的位置



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/aliyun/oss/bucket.rb', line 311

def append_object(key, pos, opts = {}, &block)
  next_pos = -1
  file = opts[:file]
  if file
    opts[:content_type] = get_content_type(file)

    next_pos = @protocol.append_object(name, key, pos, opts) do |sw|
      File.open(File.expand_path(file), 'rb') do |f|
        sw << f.read(Protocol::STREAM_CHUNK_SIZE) until f.eof?
      end
    end
  else
    next_pos = @protocol.append_object(name, key, pos, opts, &block)
  end

  next_pos
end

#batch_delete_objects(keys, opts = {}) ⇒ Array<String>

批量删除object

Parameters:

  • keys (Array<String>)

    Object的名字集合

  • opts (Hash) (defaults to: {})

    删除object的选项(可选)

Options Hash (opts):

  • :quiet (Boolean)

    指定是否允许Server返回成功删除的 object

  • :encoding (String)

    指定Server返回的成功删除的 object的名字的编码方式,目前只支持KeyEncoding::URL

Returns:

  • (Array<String>)

    成功删除的object的名字,如果指定 了:quiet参数,则返回[]



366
367
368
# File 'lib/aliyun/oss/bucket.rb', line 366

def batch_delete_objects(keys, opts = {})
  @protocol.batch_delete_objects(name, keys, opts)
end

#bucket_urlString

获取Bucket的URL

Returns:



494
495
496
# File 'lib/aliyun/oss/bucket.rb', line 494

def bucket_url
  @protocol.get_request_url(name)
end

#copy_object(source, dest, opts = {}) ⇒ Hash

将Bucket中的一个object拷贝成另外一个object

Parameters:

  • source (String)

    源object名字

  • dest (String)

    目标object名字

  • opts (Hash) (defaults to: {})

    拷贝object时的选项(可选)

Options Hash (opts):

  • :acl (String)

    目标文件的acl属性,默认为private

  • :meta_directive (String)

    指定是否拷贝源object的 meta信息,默认为MetaDirective::COPY:即拷贝object的时 候也拷贝meta信息。

  • :metas (Hash)

    设置object的meta,这是一些用户自定 义的属性,它们会和object一起存储,在#get_object的时候会 返回这些meta。属性的key不区分大小写。例如:{ ‘year’ => ‘2015’ }。如果:meta_directive为MetaDirective::COPY,则:metas 会被忽略。

  • :condition (Hash)

    指定拷贝object需要满足的条件, 同 #get_object

Returns:

  • (Hash)

    目标文件的信息

    • :etag [String] 目标文件的ETag

    • :last_modified [Time] 目标文件的最后修改时间



347
348
349
# File 'lib/aliyun/oss/bucket.rb', line 347

def copy_object(source, dest, opts = {})
  @protocol.copy_object(name, source, dest, opts)
end

#corsArray<OSS::CORSRule>

获取Bucket的跨域资源共享(CORS)的规则

Returns:

  • (Array<OSS::CORSRule>)

    Bucket的CORS规则,如果当前 Bucket未设置CORS规则,则返回[]



113
114
115
116
117
118
119
120
121
# File 'lib/aliyun/oss/bucket.rb', line 113

def cors
  begin
    r = @protocol.get_bucket_cors(name)
  rescue ServerError => e
    raise unless e.http_code == 404
  end

  r || []
end

#cors=(rules) ⇒ Object

Note:

如果rules为空,则会删除这个bucket上的CORS配置

设置Bucket的跨域资源共享(CORS)的规则

Parameters:



126
127
128
129
130
131
132
# File 'lib/aliyun/oss/bucket.rb', line 126

def cors=(rules)
  if rules.empty?
    @protocol.delete_bucket_cors(name)
  else
    @protocol.set_bucket_cors(name, rules)
  end
end

#delete_object(key) ⇒ Object

删除一个object

Parameters:

  • key (String)

    Object的名字



353
354
355
# File 'lib/aliyun/oss/bucket.rb', line 353

def delete_object(key)
  @protocol.delete_object(name, key)
end

#get_object(key, opts = {}) {|String| ... } ⇒ OSS::Object

Note:

如果opts中指定了‘:file`,则block会被忽略

Note:

如果既没有指定‘:file`也没有指定block,则只获取Object meta而不下载Object内容

从Bucket中下载一个object

Examples:

流式下载文件

get_object('x'){ |chunk| handle_chunk_data(chunk) }

下载到本地文件

get_object('x', :file => '/tmp/x')

指定检查条件

get_object('x', :file => '/tmp/x', :condition => {:if_match_etag => 'etag'})

指定重写响应的header信息

get_object('x', :file => '/tmp/x', :rewrite => {:content_type => 'text/html'})

Parameters:

  • key (String)

    Object的名字

  • opts (Hash) (defaults to: {})

    下载Object的选项(可选)

Options Hash (opts):

  • :range (Array<Integer>)

    指定下载object的部分数据, range应只包含两个数字,表示一个*左开右闭*的bytes range

  • :file (String)

    指定将下载的object写入到文件中

  • :condition (Hash)

    指定下载object需要满足的条件

    • :if_modified_since (Time) 指定如果object的修改时间晚于这个值,则下载

    • :if_unmodified_since (Time) 指定如果object从这个时间后再无修改,则下载

    • :if_match_etag (String) 指定如果object的etag等于这个值,则下载

    • :if_unmatch_etag (String) 指定如果object的etag不等于这个值,则下载

  • :rewrite (Hash)

    指定下载object时Server端返回的响应头部字段的值

    • :content_type (String) 指定返回的响应中Content-Type的值

    • :content_language (String) 指定返回的响应中Content-Language的值

    • :expires (Time) 指定返回的响应中Expires的值

    • :cache_control (String) 指定返回的响应中Cache-Control的值

    • :content_disposition (String) 指定返回的响应中Content-Disposition的值

    • :content_encoding (String) 指定返回的响应中Content-Encoding的值

Yields:

  • (String)

    如果调用的时候传递了block,则获取到的object的数据交由block处理

Returns:



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/aliyun/oss/bucket.rb', line 240

def get_object(key, opts = {}, &block)
  obj = nil
  file = opts[:file]
  if file
    File.open(File.expand_path(file), 'wb') do |f|
      obj = @protocol.get_object(name, key, opts) do |chunk|
        f.write(chunk)
      end
    end
  elsif block
    obj = @protocol.get_object(name, key, opts, &block)
  else
    obj = @protocol.get_object_meta(name, key, opts)
  end

  obj
end

#get_object_acl(key) ⇒ String

获取object的ACL

Parameters:

  • key (String)

    Object的名字

Returns:



380
381
382
# File 'lib/aliyun/oss/bucket.rb', line 380

def get_object_acl(key)
  @protocol.get_object_acl(name, key)
end

#get_object_cors(key) ⇒ OSS::CORSRule

获取object的CORS规则

Parameters:

  • key (String)

    Object的名字

Returns:



387
388
389
# File 'lib/aliyun/oss/bucket.rb', line 387

def get_object_cors(key)
  @protocol.get_object_cors(name, key)
end

#lifecycleArray<OSS::LifeCycleRule>

获取Bucket的生命周期配置

Returns:

  • (Array<OSS::LifeCycleRule>)

    Bucket的生命周期规则,如果 当前Bucket未设置lifecycle,则返回[]



87
88
89
90
91
92
93
94
95
# File 'lib/aliyun/oss/bucket.rb', line 87

def lifecycle
  begin
    r = @protocol.get_bucket_lifecycle(name)
  rescue ServerError => e
    raise unless e.http_code == 404
  end

  r || []
end

#lifecycle=(rules) ⇒ Object

Note:

如果rules为空,则会删除这个bucket上的lifecycle配置

设置Bucket的生命周期配置

Parameters:

See Also:



102
103
104
105
106
107
108
# File 'lib/aliyun/oss/bucket.rb', line 102

def lifecycle=(rules)
  if rules.empty?
    @protocol.delete_bucket_lifecycle(name)
  else
    @protocol.put_bucket_lifecycle(name, rules)
  end
end

#list_objects(opts = {}) ⇒ Enumerator<Object>

列出bucket中的object

Examples:

假设我们有如下objects:
   /foo/bar/obj1
   /foo/bar/obj2
   ...
   /foo/bar/obj9999999
   /foo/xxx/
用'foo/'作为前缀, '/'作为分隔符, 则得到的公共前缀是:
'/foo/bar/', '/foo/xxx/'。它们恰好就是目录'/foo/'下的所有子目
录。用delimiter获取公共前缀的方法避免了查询当前bucket下的所有
 object(可能数量巨大),是用于模拟目录结构的常用做法。
all = bucket.list_objects
all.each do |i|
  if i.is_a?(Object)
    puts "Object: #{i.key}"
  else
    puts "Common prefix: #{i}"
  end
end

Parameters:

  • opts (Hash) (defaults to: {})

    查询选项

Options Hash (opts):

  • :prefix (String)

    返回的object的前缀,如果设置则只 返回那些名字以它为前缀的object

  • :delimiter (String)

    用于获取公共前缀的分隔符,从 前缀后面开始到第一个分隔符出现的位置之前的字符,作为公共前缀。

  • :encoding (String)

    指定返回的响应中object名字的编 码方法,目前只支持KeyEncoding::URL编码方式。

Returns:

  • (Enumerator<Object>)

    其中Object可能是Object,也 可能是String,此时它是一个公共前缀



167
168
169
# File 'lib/aliyun/oss/bucket.rb', line 167

def list_objects(opts = {})
  Iterator::Objects.new(@protocol, name, opts).to_enum
end

#loggingBucketLogging

获取Bucket的logging配置

Returns:



36
37
38
# File 'lib/aliyun/oss/bucket.rb', line 36

def logging
  @protocol.get_bucket_logging(name)
end

#logging=(logging) ⇒ Object

设置Bucket的logging配置

Parameters:



42
43
44
45
46
47
48
# File 'lib/aliyun/oss/bucket.rb', line 42

def logging=(logging)
  if logging.enabled?
    @protocol.put_bucket_logging(name, logging)
  else
    @protocol.delete_bucket_logging(name)
  end
end

#object_exists?(key) ⇒ Boolean Also known as: object_exist?

判断一个object是否存在

Parameters:

  • key (String)

    Object的名字

Returns:

  • (Boolean)

    如果Object存在返回true,否则返回false



277
278
279
280
281
282
283
284
285
286
287
# File 'lib/aliyun/oss/bucket.rb', line 277

def object_exists?(key)
  begin
    get_object(key)
    return true
  rescue ServerError => e
    return false if e.http_code == 404
    raise e
  end

  false
end

#object_url(key, sign = true, expiry = 60) ⇒ String

获取Object的URL

Parameters:

  • key (String)

    Object的key

  • sign (Boolean) (defaults to: true)

    是否对URL进行签名,默认为是

  • expiry (Fixnum) (defaults to: 60)

    URL的有效时间,单位为秒,默认为60s

Returns:

  • (String)

    用于直接访问Object的URL



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
# File 'lib/aliyun/oss/bucket.rb', line 503

def object_url(key, sign = true, expiry = 60)
  url = @protocol.get_request_url(name, key)
  return url unless sign

  expires = Time.now.to_i + expiry
  string_to_sign = "GET\n" +
                   "\n\n" +
                   "#{expires}\n" +
                   "/#{name}/#{key}"
  signature = sign(string_to_sign)

  query_string = {
    'Expires' => expires.to_s,
    'OSSAccessKeyId' => CGI.escape(access_key_id),
    'Signature' => CGI.escape(signature)
  }.map { |k, v| "#{k}=#{v}" }.join('&')

  [url, query_string].join('?')
end

#put_object(key, opts = {}) {|HTTP::StreamWriter| ... } ⇒ Object

Note:

采用streaming的方式时,提供的数据必须是有结束标记的数据。 因为put_object会不断地从StreamWriter中读取数据上传到OSS,直到 它读到的数据为nil停止。

Note:

如果opts中指定了:file,则block会被忽略

向Bucket中上传一个object

Examples:

流式上传数据

put_object('x'){ |stream| 100.times { |i| stream << i.to_s } }
put_object('x'){ |stream| stream << get_data }

上传文件

put_object('x', :file => '/tmp/x')

指定Content-Type和metas

put_object('x', :file => '/tmp/x', :content_type => 'text/html',
           :metas => {'year' => '2015', 'people' => 'mary'})

Parameters:

  • key (String)

    Object的名字

  • opts (Hash) (defaults to: {})

    上传object时的选项(可选)

Options Hash (opts):

  • :file (String)

    设置所上传的文件

  • :content_type (String)

    设置所上传的内容的 Content-Type,默认是application/octet-stream

  • :metas (Hash)

    设置object的meta,这是一些用户自定 义的属性,它们会和object一起存储,在#get_object的时候会 返回这些meta。属性的key不区分大小写。例如:{ ‘year’ => ‘2015’ }

Yields:

  • (HTTP::StreamWriter)

    如果调 用的时候传递了block,则写入到object的数据由block指定



194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/aliyun/oss/bucket.rb', line 194

def put_object(key, opts = {}, &block)
  file = opts[:file]
  if file
    opts[:content_type] = get_content_type(file)

    @protocol.put_object(name, key, opts) do |sw|
      File.open(File.expand_path(file), 'rb') do |f|
        sw << f.read(Protocol::STREAM_CHUNK_SIZE) until f.eof?
      end
    end
  else
    @protocol.put_object(name, key, opts, &block)
  end
end

#refererBucketReferer

获取Bucket的Referer配置

Returns:



74
75
76
# File 'lib/aliyun/oss/bucket.rb', line 74

def referer
  @protocol.get_bucket_referer(name)
end

#referer=(referer) ⇒ Object

设置Bucket的Referer配置

Parameters:



80
81
82
# File 'lib/aliyun/oss/bucket.rb', line 80

def referer=(referer)
  @protocol.put_bucket_referer(name, referer)
end

#resumable_download(key, file, opts = {}) {|Float| ... } ⇒ Object

Note:

已经下载的部分会在file所在的目录创建.part文件,命名方式 为file.part.N

下载bucket中的一个object到本地文件,支持断点续传。指定的object 会被分成多个分片进行下载,只有所有的分片都下载成功整个object才 下载成功。对于每个下载的分片,会在file所在目录建立一个临时文件 file.part.N,下载成功后这些part文件会被合并成最后的file然后删 除。

Examples:

bucket.resumable_download('my-object', '/tmp/x') do |p|
  puts "Progress: #{(p * 100).round(2)} %"
end

Parameters:

  • key (String)

    Object的名字

  • file (String)

    本地文件的路径

  • opts (Hash) (defaults to: {})

    下载文件的可选项

Options Hash (opts):

  • :part_size (Integer)

    设置分片上传时每个分片的大小, 默认为1 MB。断点下载最多允许100个分片,如果文件大于100个分片, 则每个分片的大小会大于1MB

  • :cpt_file (String)

    断点续传的checkpoint文件,如果 指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, 命名方式为:file.cpt,其中file是用户要下载的文件名。在下载的过 程中会不断更新此文件,成功完成下载后会删除此文件;如果指定的 cpt文件已存在,则从cpt文件中记录的点继续下载。

  • :disable_cpt (Boolean)

    是否禁用checkpoint功能,如 果设置为true,则在下载的过程中不会写checkpoint文件,这意味着 下载失败后不能断点续传,而只能重新下载整个文件。如果这个值为true, 则:cpt_file会被忽略。

  • :condition (Hash)

    指定下载object需要满足的条件, 同 #get_object

  • :rewrite (Hash)

    指定下载object时Server端返回的响 应头部字段的值,同 #get_object

Yields:

  • (Float)

    如果调用的时候传递了block,则会将下载进度交由 block处理,进度值是一个0-1之间的小数

Raises:

  • (CheckpointBrokenError)

    如果cpt文件被损坏,则抛出此错误

  • (ObjectInconsistentError)

    如果指定的object的etag与cpt文 件中记录的不一致,则抛出错误

  • (PartMissingError)

    如果已下载的部分(.part文件)找不到, 则抛出此错误

  • (PartInconsistentError)

    如果已下载的部分(.part文件)的 MD5值与cpt文件记录的不一致,则抛出此错误



479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/aliyun/oss/bucket.rb', line 479

def resumable_download(key, file, opts = {}, &block)
  unless cpt_file = opts[:cpt_file]
    cpt_file = get_cpt_file(file)
  end

  Multipart::Download.new(
    @protocol, options: opts,
    progress: block,
    object: key, bucket: name, creation_time: Time.now,
    file: File.expand_path(file), cpt_file: cpt_file
  ).run
end

#resumable_upload(key, file, opts = {}) {|Float| ... } ⇒ Object

上传一个本地文件到bucket中的一个object,支持断点续传。指定的文 件会被分成多个分片进行上传,只有所有分片都上传成功整个文件才 上传成功。

Examples:

bucket.resumable_upload('my-object', '/tmp/x') do |p|
  puts "Progress: #{(p * 100).round(2)} %"
end

Parameters:

  • key (String)

    Object的名字

  • file (String)

    本地文件的路径

  • opts (Hash) (defaults to: {})

    上传文件的可选项

Options Hash (opts):

  • :content_type (String)

    设置所上传的内容的 Content-Type,默认是application/octet-stream

  • :metas (Hash)

    设置object的meta,这是一些用户自定 义的属性,它们会和object一起存储,在#get_object的时候会 返回这些meta。属性的key不区分大小写。例如:{ ‘year’ => ‘2015’ }

  • :part_size (Integer)

    设置分片上传时每个分片的大小, 默认为1 MB。断点上传最多允许10000个分片,如果文件大于10000个 分片的大小,则每个分片的大小会大于1MB。

  • :cpt_file (String)

    断点续传的checkpoint文件,如果 指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, 命名方式为:file.cpt,其中file是用户要上传的文件。在上传的过 程中会不断更新此文件,成功完成上传后会删除此文件;如果指定的 cpt文件已存在,则从cpt文件中记录的点继续上传。

  • :disable_cpt (Boolean)

    是否禁用checkpoint功能,如 果设置为true,则在上传的过程中不会写checkpoint文件,这意味着 上传失败后不能断点续传,而只能重新上传整个文件。如果这个值为 true,则:cpt_file会被忽略。

Yields:

  • (Float)

    如果调用的时候传递了block,则会将上传进度交由 block处理,进度值是一个0-1之间的小数

Raises:



427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/aliyun/oss/bucket.rb', line 427

def resumable_upload(key, file, opts = {}, &block)
  unless cpt_file = opts[:cpt_file]
    cpt_file = get_cpt_file(file)
  end

  Multipart::Upload.new(
    @protocol, options: opts,
    progress: block,
    object: key, bucket: name, creation_time: Time.now,
    file: File.expand_path(file), cpt_file: cpt_file
  ).run
end

#set_object_acl(key, acl) ⇒ Object

设置object的ACL

Parameters:



373
374
375
# File 'lib/aliyun/oss/bucket.rb', line 373

def set_object_acl(key, acl)
  @protocol.put_object_acl(name, key, acl)
end

#sign(string_to_sign) ⇒ String

用ACCESS_KEY_SECRET对内容进行签名

Parameters:

  • string_to_sign (String)

    要进行签名的内容

Returns:

  • (String)

    生成的签名



532
533
534
# File 'lib/aliyun/oss/bucket.rb', line 532

def sign(string_to_sign)
  @protocol.sign(string_to_sign)
end

#update_object_metas(key, metas, conditions = {}) ⇒ Hash

更新Object的metas

Parameters:

  • key (String)

    Object的名字

  • metas (Hash)

    Object的meta

  • conditions (Hash) (defaults to: {})

    指定更新Object meta需要满足的条件, 同#get_object

Returns:

  • (Hash)

    更新后文件的信息

    • :etag [String] 更新后文件的ETag

    • :last_modified [Time] 更新后文件的最后修改时间



266
267
268
269
270
271
272
# File 'lib/aliyun/oss/bucket.rb', line 266

def update_object_metas(key, metas, conditions = {})
  @protocol.copy_object(
    name, key, key,
    :meta_directive => MetaDirective::REPLACE,
    :metas => metas,
    :condition => conditions)
end

#websiteBucketWebsite

获取Bucket的website配置

Returns:



52
53
54
55
56
57
58
59
60
# File 'lib/aliyun/oss/bucket.rb', line 52

def website
  begin
    w = @protocol.get_bucket_website(name)
  rescue ServerError => e
    raise unless e.http_code == 404
  end

  w || BucketWebsite.new
end

#website=(website) ⇒ Object

设置Bucket的website配置

Parameters:



64
65
66
67
68
69
70
# File 'lib/aliyun/oss/bucket.rb', line 64

def website=(website)
  if website.enabled?
    @protocol.put_bucket_website(name, website)
  else
    @protocol.delete_bucket_website(name)
  end
end