我的公司将数据消息 (json) 存储在 Amazon S3 上的 gzip 文件中。我想使用 Ruby 来遍历文件并进行一些分析。我开始使用“aws/s3”gem,并将每个文件作为一个对象获取:
#<AWS::S3::S3Object:0x4xxx4760 '/my.company.archive/data/msg/20131030093336.json.gz'>
但是一旦我有了这个对象,我就不知道如何解压它,甚至不知道如何访问它里面的数据。
我的公司将数据消息 (json) 存储在 Amazon S3 上的 gzip 文件中。我想使用 Ruby 来遍历文件并进行一些分析。我开始使用“aws/s3”gem,并将每个文件作为一个对象获取:
#<AWS::S3::S3Object:0x4xxx4760 '/my.company.archive/data/msg/20131030093336.json.gz'>
但是一旦我有了这个对象,我就不知道如何解压它,甚至不知道如何访问它里面的数据。
您可以在此处查看文档:http S3Object
: //amazon.rubyforge.org/doc/classes/AWS/S3/S3Object.html。
您可以通过调用获取内容your_object.value
;看看你能不能走到那一步。那么应该是解压gzip blob的问题了。Zlib
应该能够处理。
我不确定是否.value
会返回一大串二进制数据或 IO 对象。如果它是一个字符串,您可以将它包装在一个StringIO
对象中以将其传递给Zlib::GzipReader.new
,例如
json_data = Zlib::GzipReader.new(StringIO.new(your_object.value)).read
S3Object
有一个stream
方法,我希望它的行为像一个 IO 对象(我不能在这里测试,抱歉)。如果是这样,你可以这样做:
json_data = Zlib::GzipReader.new(your_object.stream).read
一旦你有解压缩的 json 内容,你就可以调用JSON.parse
它,例如
JSON.parse Zlib::GzipReader.new(StringIO.new(your_object.value)).read
对我来说,以下一组步骤有效:
file_path = "/tmp/gz/x.csv.gz"
File.open(file_path, mode="wb") do |f|
s3_client.get_object(bucket: bucket, key: key) do |gzfiledata|
f.write gzfiledata
end
end
data = []
Zlib::GzipReader.open(file_path) do |gz_reader|
csv_reader = ::FastestCSV.new(gz_reader)
csv_reader.each do |csv|
data << csv
end
end
S3Object
文档已更新,该方法stream
不再可用:https ://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html
因此,从 S3 对象读取数据的最佳方法是:
json_data = Zlib::GzipReader.new(StringIO.new(your_object.read)).read