我编写了一个脚本,通过我的Rackspace cloudfiles容器递归下载并检索每个文件的副本,因此我有一个本地备份,以防Rackspace受到流星和/或hindenbugs的攻击。</ p>
但是,我的脚本在下载文件时显然会以线性比例泄漏内存。
基本上我有一个看起来像这样的方法:
def download_file(fog_file, destination_path)
data = fog_file.body
File.open(destination_path, 'w') { |f| f.write(data) }
end
据我所知,由于Fog的性质,我无法避免将整个文件加载到内存中,但我认为Ruby会在每次download_file
调用后释放内存(或具有释放内存的能力)。毕竟,data
变量超出了范围。
不幸的是,当我查看系统监控时,内存使用量会以线性速度增长,直到它消耗掉所有可用内存,此时脚本崩溃。
我在这里做错了什么?
我在Ubuntu上使用Ruby 2.1.2。
答案 0 :(得分:1)
您可以避免以两种方式将整个文件加载到内存中。
首先,您可以在100kb(或更少)chucks中检索文件:
service = Fog::Storage.new({ provider: 'Rackspace',
# ... auth config
connection_options: {chunk_size: 102_400} # 100 KB in bytes
})
directory = service.directories.get "dir"
File.open((destination_path, 'w') do | f |
directory.files.get("my_file_on_cloud.png") do | data, remaining, content_length |
f.syswrite data
end
end
其次,您可以使用雾检索文件URL,然后使用OpenUri下载并保存文件:
require 'open-uri'
file = open(file.public_url).read
File.open(destination_path, 'w') { |f| f.write(file) }
第一种方法直接写入目标文件,第二种方法创建Tempfile
实例(在文件系统上创建临时文件)。试试两个。