class COS::Bucket
Constants
- DEFAULT_DOWNLOAD_RETRY
默认下载重试次数
- DEFAULT_UPLOAD_RETRY
默认上传重试次数
- MIN_DOWNLOAD_SLICE_SIZE
最小下载分块大小
- MIN_UPLOAD_SLICE_SIZE
最小完整上传大小
Attributes
Public Class Methods
初始化
@note SDK会自动获取bucket的信息,包括读取权限等并进行缓存
如需在后台修改了bucket信息请重新初始化Client
@param client [COS::Client] @param bucket_name
[String] bucket名称
如果在初始化时的配置中设置了default_bucket则该字段可以为空,会获取默认的bucket
@return [COS::Bucket]DEFAULT_UPLOAD_RETRY
@raise [ClientError] 未指定bucket @raise [ServerError] bucket不存在
# File lib/cos/bucket.rb, line 40 def initialize(client, bucket_name = nil) @client = client @bucket_name = client.config.get_bucket(bucket_name) # 使用stat API 获取根目录信息可获取到bucket信息 data = client.api.stat('/', bucket: bucket_name) @authority = data[:authority] @bucket_type = data[:bucket_type] @need_preview = data[:need_preview] @refers = data[:refers] @migrate_source_domain = data[:migrate_source_domain] @blackrefers = data[:blackrefers] @brower_exec = data[:brower_exec] @cnames = data[:cnames] @nugc_flag = data[:nugc_flag] end
Public Instance Methods
判断文件是否上传完成
@param path [String] 文件资源路径, 如: ‘path1/file’
@raise [ServerError] 服务端异常返回
@return [Boolean] 是否完成
@example
puts bucket.complete?('path1/file1')
# File lib/cos/bucket.rb, line 425 def complete?(path) get_file(path).complete? end
获取文件及目录总数
@param path [String] 目录路径, 如: ‘path1’, ‘path1/path2’, sdk会补齐末尾的 ‘/’
@return [Integer] 文件及目录总数
@raise [ServerError] 服务端异常返回
# File lib/cos/bucket.rb, line 113 def count(path = '') lc = list_count(path) lc[:total] end
获取目录数
@param path [String] 目录路径, 如: ‘path1’, ‘path1/path2’, sdk会补齐末尾的 ‘/’
@return [Integer] 目录数
@raise [ServerError] 服务端异常返回
# File lib/cos/bucket.rb, line 139 def count_dirs(path = '') lc = list_count(path) lc[:dirs] end
获取文件数
@param path [String] 目录路径, 如: ‘path1’, ‘path1/path2’, sdk会补齐末尾的 ‘/’
@return [Integer] 文件数
@raise [ServerError] 服务端异常返回
# File lib/cos/bucket.rb, line 127 def count_files(path = '') lc = list_count(path) lc[:files] end
创建目录
@see API#create_folder
@param path [String] 目录路径, 如: ‘path1’, ‘path1/path2’, sdk会补齐末尾的 ‘/’ @param options [Hash] 高级参数 @option options [String] :biz_attr 目录属性, 业务端维护
@return [COS::COSDir]
@raise [ServerError] 服务端异常返回
# File lib/cos/bucket.rb, line 68 def create_folder(path, options = {}) data = client.api.create_folder(path, options.merge({bucket: bucket_name})) dir = { mtime: data[:mtime], ctime: data[:ctime], name: data[:name], biz_attr: options[:biz_attr], bucket: self, path: path } COSDir.new(dir) end
删除文件或目录
@note 非空目录及根目录不可删除,会抛出异常
@param path [String] 资源路径, 如: 目录‘path1/’, 文件‘path1/file’
@raise [ServerError] 服务端异常返回
@example
bucket.delete('path1/file')
# File lib/cos/bucket.rb, line 359 def delete(path) client.api.delete(path, bucket: bucket_name) end
删除文件或目录, 不会抛出异常而是返回布尔值
@note 非空目录及根目录不可删除, 返回false
@param path [String] 资源路径, 如: 目录‘path1/’, 文件‘path1/file’
@example
puts bucket.delete!('path1/file')
# File lib/cos/bucket.rb, line 371 def delete!(path) delete(path) true rescue false end
下载文件, 支持断点续传, 支持多线程
@param path_or_file [String|COS::COSFile] 文件路径或文件对象COSFile @param file_store [String] 本地文件存储路径 @param options [Hash] 高级参数 @option options [Integer] :min_slice_size 完整下载最小文件大小,
超过此大小将会使用分片多线程断点续传
@option options [Integer] :download_retry 下载重试次数, 默认10 @option options [Boolean] :disable_cpt 是否禁用checkpoint功能,如
果设置为true,则在下载的过程中不会写checkpoint文件,这意味着 下载失败后不能断点续传,而只能重新下载整个文件。如果这个值为 true,则:cpt_file会被忽略。
@option options [Integer] :threads 多线程下载线程数, 默认为10 @option options [Integer] :slice_size 设置分片下载时每个分片的大小
默认为5 MB。
@option options [String] :cpt_file 断点续传的checkpoint文件,如果
指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, 命名方式为:file.cpt,其中file是用户要下载的文件名。在下载的过 程中会不断更新此文件,成功完成下载后会删除此文件;如果指定的 cpt文件已存在,则从cpt文件中记录的点继续下载。
@yield [Float] 下载进度百分比回调, 进度值是一个0-1之间的小数
@raise [ServerError] 服务端异常返回
@return [String]
@example
file = bucket.download('path/file1', '~/test/file1') do |p| puts "下载进度: #{(p*100).round(2)}%") end puts file
# File lib/cos/bucket.rb, line 506 def download(path_or_file, file_store, options = {}, &block) min_size = options[:min_slice_size] || MIN_DOWNLOAD_SLICE_SIZE retry_times = options[:download_retry] || DEFAULT_DOWNLOAD_RETRY # 如果传入的是一个路径需要先获取文件信息 file = get_file(path_or_file) # 检查文件是否上传完整才能下载 unless file.complete? raise FileUploadNotComplete, 'file upload not complete' end # 检查本地文件sha1是否一致, 如一致就已下载完成了 if file.sha1_match?(file_store) logger.info("File #{file_store} exist and sha1 match, skip download.") return file_store end retry_loop(retry_times) do if file.filesize > min_size # 分块下载 Download.new( bucket: self, cos_file: file, file_store: file_store, options: options, progress: block ).download else # 直接下载 client.api.download(file.access_url, file_store, bucket: bucket_name) end end # 返回本地文件路径 file_store end
批量下载目录下的全部文件(不包含子目录)
@note sdk会自动创建本地目录
@param path_or_dir [String|COS::COSDir] 目录路径或目录对象COSDir
目录路径如: '/', 'path1', 'path1/path2', sdk会补齐末尾的 '/'
@param file_store_path [String] 本地文件存储目录 @param options [Hash] 高级参数 @option options [Integer] :min_slice_size 完整下载最小文件大小,
超过此大小将会使用分片多线程断点续传
@option options [Integer] :disable_mkdir 禁止自动创建本地文件夹, 默认会创建 @option options [Integer] :download_retry 下载重试次数, 默认10 @option options [Boolean] :disable_cpt 是否禁用checkpoint功能,如
果设置为true,则在下载的过程中不会写checkpoint文件,这意味着 下载失败后不能断点续传,而只能重新下载整个文件。如果这个值为 true,则:cpt_file会被忽略。
@option options [Integer] :threads 多线程下载线程数, 默认为10 @option options [Integer] :slice_size 设置分片下载时每个分片的大小
默认为5 MB。
@option options [String] :cpt_file 断点续传的checkpoint文件,如果
指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, 命名方式为:file.cpt,其中file是用户要下载的文件名。在下载的过 程中会不断更新此文件,成功完成下载后会删除此文件;如果指定的 cpt文件已存在,则从cpt文件中记录的点继续下载。
@yield [Float] 下载进度百分比回调, 进度值是一个0-1之间的小数
@raise [ServerError] 服务端异常返回
@return [Array<String>] 本地文件路径数组
@example
files = bucket.download_all('path/', '~/test/') do |p| puts "下载进度: #{(p*100).round(2)}%") end puts files
# File lib/cos/bucket.rb, line 582 def download_all(path_or_dir, file_store_path, options = {}, &block) local_path = Util.get_local_path(file_store_path, options[:disable_mkdir]) dir = get_dir(path_or_dir) downloaded = [] # 遍历目录下的所有文件 dir.list(pattern: :file_only).each do |file| logger.info("Begin to download file >> #{file.name}") downloaded << file.download("#{local_path}/#{file.name}", options, &block) logger.info("#{file.name} download finished") end downloaded end
目录是否是空的
@param path [String] 资源路径, 如: 目录‘path1/’
@raise [ServerError] 服务端异常返回
@return [Boolean] 是否为空
@example
puts bucket.empty?('path1/')
# File lib/cos/bucket.rb, line 388 def empty?(path = '') count(path) == 0 end
文件或目录是否存在
@param path [String] 资源路径, 如: 目录‘path1/’, 文件‘path1/file’
@raise [ServerError] 服务端异常返回
@return [Boolean] 是否存在
@example
puts bucket.exist?('path1/file1')
# File lib/cos/bucket.rb, line 402 def exist?(path) begin stat(path) rescue ServerError => e return false if e.error_code == -166 raise e end true end
获取Hash格式的目录树形结构, 可用于直接to_json
@param path_or_dir [String|COS::COSDir] 目录路径或目录对象COSDir
目录路径如: '/', 'path1', 'path1/path2', sdk会补齐末尾的 '/'
@param options [Hash] @option options [Integer] :depth 子目录深度,默认为5
@raise [ServerError] 服务端异常返回
@return [Hash<Object>]
@example
puts bucket.hash_tree.to_json
{
:resource => {name: '', mtime: ''...}, :children => [ {:resource => resource, :children => [...]}, {:resource => resource, :children => [...]}, ... ]
}
# File lib/cos/bucket.rb, line 652 def hash_tree(path_or_dir = '', options = {}) dir = get_dir(path_or_dir) Tree.new(options.merge({path: dir})).to_hash end
列出目录
@param path [String] 目录路径, 如: ‘/’, ‘path1’, ‘path1/path2’, sdk会补齐末尾的 ‘/’ @param options [Hash] @option options [String] :prefix 搜索前缀
如果填写prefix, 则列出含此前缀的所有文件及目录
@option options [Integer] :num 每页拉取的数量, 默认20条 @option options [Symbol] :pattern 获取方式
:dir_only 只获取目录, :file_only 只获取文件, 默认为 :both 全部获取
@option options [Symbol] :order 排序方式 :asc 正序, :desc 倒序 默认为 :asc
@raise [ServerError] 服务端异常返回
@return [Enumerator<Object>] 迭代器, 其中Object可能是COS::COSFile或COS::COSDir
@example
all = bucket.list all.each do |o| if o.is_a?(COS::COSFile) puts "File: #{o.name} #{o.format_size}" else puts "Dir: #{o.name} #{o.created_at}" end end
# File lib/cos/bucket.rb, line 168 def list(path = '', options = {}) Resource.new(self, path, options).to_enum end
获取list中的文件及目录个数
@param path [String] 目录路径, 如: ‘path1’, ‘path1/path2’, sdk会补齐末尾的 ‘/’
@param options [Hash] @option options [String] :prefix 搜索前缀
如果填写prefix, 则计算含此前缀的所有文件及目录个数
@return [Hash]
* :total [Integer] 文件和目录总数 * :files [Integer] 文件数 * :dirs [Integer] 目录数
@raise [ServerError] 服务端异常返回
# File lib/cos/bucket.rb, line 98 def list_count(path = '', options = {}) options = {} result = client.api.list(path, options.merge({num: 1, bucket: bucket_name})) total = result[:filecount] + result[:dircount] {total: total, files: result[:filecount], dirs: result[:dircount]} end
获取文件或目录信息
@note 如查询根目录(‘/’, ”)可以获取到bucket信息, 返回COSDir
@param path [String] 资源路径, 如: 目录‘path1/’, 文件‘path1/file’
@raise [ServerError] 服务端异常返回
@return [COSFile|COSDir] 如果是目录则返回COSDir资源对象,是文件则返回COSFile资源对象
@example
puts bucket.stat('path1/file').name
# File lib/cos/bucket.rb, line 321 def stat(path = '') data = client.api.stat(path, bucket: bucket_name) # 查询'/'获取的是bucket信息, 无name参数, 需要补全 data[:name] = '' if data[:name].nil? if data[:filesize].nil? # 目录 COSDir.new(data.merge({bucket: self, path: path})) else # 文件 COSFile.new(data.merge({bucket: self, path: path})) end end
获取目录树形结构
@param path_or_dir [String|COS::COSDir] 目录路径或目录对象COSDir
目录路径如: '/', 'path1', 'path1/path2', sdk会补齐末尾的 '/'
@param options [Hash] @option options [Integer] :depth 子目录深度,默认为5
@raise [ServerError] 服务端异常返回
@return [Hash]
@example
tree = bucket.tree puts tree[:resource].name tree[:children].each do |r| puts r[:resource].name end
{
:resource => resource, :children => [ {:resource => resource, :children => [...]}, {:resource => resource, :children => [...]}, ... ]
}
# File lib/cos/bucket.rb, line 625 def tree(path_or_dir = '', options = {}) dir = get_dir(path_or_dir) Tree.new(options.merge({path: dir})).to_object end
更新文件及目录业务属性
@param path [String] 资源路径, 如: 目录‘path1/’, 文件‘path1/file’ @param biz_attr [String] 目录/文件属性,业务端维护
@raise [ServerError] 服务端异常返回
@example
bucket.update('path1/file', 'i am the attr')
# File lib/cos/bucket.rb, line 345 def update(path, biz_attr) client.api.update(path, biz_attr, bucket: bucket_name) end
上传文件, 大文件自动断点续传, 多线程上传
@param path_or_dir [String|COS::COSDir] 目录路径或目录对象COSDir
目录路径如: '/', 'path1', 'path1/path2', sdk会补齐末尾的 '/'
@param file_name [String] 文件名 @param file_src [String] 本地文件路径 @param options [Hash] 高级参数 @option options [Boolean] :auto_create_folder 自动创建远端目录 @option options [Integer] :min_slice_size 完整上传最小文件大小,
超过此大小将会使用分片多线程断点续传
@option options [Integer] :upload_retry 上传重试次数, 默认10 @option options [String] :biz_attr 目录属性, 业务端维护 @option options [Boolean] :disable_cpt 是否禁用checkpoint功能,如
果设置为true,则在上传的过程中不会写checkpoint文件,这意味着 上传失败后不能断点续传,而只能重新上传整个文件。如果这个值为 true,则:cpt_file会被忽略。
@option options [Integer] :threads 多线程上传线程数, 默认为10 @option options [Integer] :slice_size 设置分片上传时每个分片的大小
默认为3 MB, 目前服务端最大限制也为3MB。
@option options [String] :cpt_file 断点续传的checkpoint文件,如果
指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, 命名方式为:file.cpt,其中file是用户要上传的文件名。在上传的过 程中会不断更新此文件,成功完成上传后会删除此文件;如果指定的 cpt文件已存在,则从cpt文件中记录的点继续上传。
@yield [Float] 上传进度百分比回调, 进度值是一个0-1之间的小数
@raise [ServerError] 服务端异常返回
@return [COS::COSFile]
@example
file = bucket.upload('path', 'file1', '~/test/file1') do |p| puts "上传进度: #{(p*100).round(2)}%") end puts file.url
# File lib/cos/bucket.rb, line 210 def upload(path_or_dir, file_name, file_src, options = {}, &block) dir = get_dir(path_or_dir, options[:auto_create_folder]) min_size = options[:min_slice_size] || MIN_UPLOAD_SLICE_SIZE retry_times = options[:upload_retry] || DEFAULT_UPLOAD_RETRY if min_size > 20 * 1024 * 1024 raise EntireUploadTooLarge, 'entire upload file too large, file size must < 20MB' end options.merge!({bucket: bucket_name}) file_src = File.expand_path(file_src) file_size = File.size(file_src) retry_loop(retry_times) do if file_size > min_size # 分块上传 client.api.upload_slice(dir.path, file_name, file_src, options, &block) else # 完整上传 client.api.upload(dir.path, file_name, file_src, options) end end # 获取上传完成文件的状态, 只会返回<COSFile> stat(Util.get_list_path(dir.path, file_name, true)) end
批量上传目录下的全部文件(不包含子目录)
@note 已存在的文件不会再次上传, 本地目录中的隐藏文件(已“.”开头的)不会上传
".cpt"文件不会上传, 不会上传子目录
@param path_or_dir [String|COS::COSDir] 目录路径或目录对象COSDir
目录路径如: '/', 'path1', 'path1/path2', sdk会补齐末尾的 '/'
@param file_src_path [String] 本地文件夹路径 @param options [Hash] 高级参数 @option options [Boolean] :auto_create_folder 自动创建远端目录 @option options [Integer] :min_slice_size 完整上传最小文件大小,
超过此大小将会使用分片多线程断点续传
@option options [Integer] :upload_retry 上传重试次数, 默认10 @option options [String] :biz_attr 目录属性, 业务端维护 @option options [Boolean] :disable_cpt 是否禁用checkpoint功能,如
果设置为true,则在上传的过程中不会写checkpoint文件,这意味着 上传失败后不能断点续传,而只能重新上传整个文件。如果这个值为 true,则:cpt_file会被忽略。
@option options [Integer] :threads 多线程上传线程数, 默认为10 @option options [Integer] :slice_size 设置分片上传时每个分片的大小
默认为3 MB, 目前服务端最大限制也为3MB。
@option options [String] :cpt_file 断点续传的checkpoint文件,如果
指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, 命名方式为:file.cpt,其中file是用户要上传的文件名。在上传的过 程中会不断更新此文件,成功完成上传后会删除此文件;如果指定的 cpt文件已存在,则从cpt文件中记录的点继续上传。
@yield [Float] 上传进度百分比回调, 进度值是一个0-1之间的小数
@raise [ServerError] 服务端异常返回
@return [Array<COS::COSFile>]
@example
files = bucket.upload_all('path', '~/test') do |p| puts "上传进度: #{(p*100).round(2)}%") end files.each do |file| puts file.url end
# File lib/cos/bucket.rb, line 278 def upload_all(path_or_dir, file_src_path, options = {}, &block) local_path = Util.get_local_path(file_src_path, true) uploaded = [] Dir.foreach(local_path) do |file| if !file.start_with?('.') and !file.end_with?('.cpt') and !File.directory?(file) logger.info("Begin to upload file >> #{file}") begin # 逐个上传 uploaded << upload(path_or_dir, file, "#{local_path}/#{file}", options, &block) rescue => error # 跳过错误 if options[:skip_error] logger.info("#{file} error skipped") next else # 终止上传抛出异常 raise error end end logger.info("#{file} upload finished") end end uploaded end
获取文件可访问的URL
@note 私有读取的bucket会自动生成带签名的URL
@param path_or_file [String|COS::COSFile] 文件资源COSFile或路径, 如: ‘path1/file’ @param options [Hash] 高级参数 @option options [String] :cname 在cos控制台设置的cname域名 @option options [Boolean] :https 是否生成https的URL @option options [Integer] :expire_seconds 签名有效时间(秒,私有读取bucket时需要)
@raise [ServerError] 服务端异常返回
@return [String] 文件访问URL
@example
puts bucket.url('path1/file1', https: true, cname: 'static.domain.com')
# File lib/cos/bucket.rb, line 445 def url(path_or_file, options = {}) file = get_file(path_or_file) url = file.access_url # 使用cname if options[:cname] host = URI.parse(url).host.downcase url.gsub!(host, options[:cname]) end # 使用https if options[:https] url.gsub!('http://', 'https://') end if authority == 'eWRPrivate' # 私有读取的bucket自动生成带签名的URL sign = client.signature.multiple( bucket_name, options[:expire_seconds] || client.config.multiple_sign_expire) "#{url}?sign=#{sign}" else url end end
Private Instance Methods
获取目录对象, 可接受path string或COSDir
# File lib/cos/bucket.rb, line 696 def get_dir(path_or_dir, auto_create_folder = false) if path_or_dir.is_a?(COS::COSDir) # 传入的是COSDir path_or_dir elsif path_or_dir.is_a?(String) # 传入的是path string path_or_dir = "#{path_or_dir}/" unless path_or_dir.end_with?('/') dir = handle_folder(path_or_dir, auto_create_folder) get_dir(dir) else raise ClientError, "can't get dir from #{path_or_dir.class}, " \ 'must be a file path string or COS::COSDir' end end
获取文件对象, 可接受path string或COSFile
# File lib/cos/bucket.rb, line 677 def get_file(path_or_file) if path_or_file.is_a?(COS::COSFile) # 传入的是COSFile path_or_file elsif path_or_file.is_a?(String) # 传入的是path string file = stat(path_or_file) get_file(file) else raise ClientError, "can't get file from #{path_or_file.class}, " \ 'must be a file path string or COS::COSFile' end end
获取目录信息并可以自动创建目录
# File lib/cos/bucket.rb, line 717 def handle_folder(path_or_dir, auto_create_folder = false) return stat(path_or_dir) rescue => error unless auto_create_folder raise error end # 自动创建目录 if error.is_a?(COS::ServerError) and error.error_code == -166 logger.info('path not exist, auto create folder...') return create_folder(path_or_dir) end raise error end
重试循环
# File lib/cos/bucket.rb, line 660 def retry_loop(retry_times, &block) begin block.call rescue => error if retry_times > 0 retry_times -= 1 logger.info('Retrying...') retry else raise error end end end