Zlib::GzipReader
hoạt động giống như hầu hết các lớp giống như IO
giống như trong Ruby. Bạn có một cuộc gọi open
và khi bạn chuyển một khối cho nó, khối sẽ nhận được đối tượng giống như IO
. Hãy suy nghĩ về nó là cách thuận tiện để làm một cái gì đó với một tập tin hoặc tài nguyên trong suốt thời gian của khối.
Nhưng điều đó có nghĩa là trong ví dụ gz
của bạn là một đối tượng giống như IO
và không thực sự là nội dung của tệp gzip, như bạn mong đợi. Bạn vẫn cần phải read
để thực hiện điều đó. Việc sửa chữa đơn giản nhất sau đó sẽ là:
g.write(gz.read)
Lưu ý rằng điều này sẽ đọc toàn bộ nội dung của nén gzip vào bộ nhớ.
Nếu tất cả những gì bạn thực sự đang làm là sao chép từ tệp này sang tệp khác, bạn có thể sử dụng phương thức IO.copy_stream
hiệu quả hơn. Ví dụ của bạn có thể trông giống như sau:
Zlib::GzipReader.open('PRIDE_Exp_Complete_Ac_1015.xml.gz') do | input_stream |
File.open("PRIDE_Exp_Complete_Ac_1015.xml", "w") do |output_stream|
IO.copy_stream(input_stream, output_stream)
end
end
Phía sau hậu trường, điều này sẽ cố gắng sử dụng syscall sendfile
có sẵn trong một số tình huống cụ thể trên Linux. Nếu không, nó sẽ thực hiện sao chép trong các khối mã 16KB mã C nhanh tại một thời điểm. Điều này tôi đã học được từ mã nguồn Ruby 1.9.1.
Nguồn
2010-07-02 22:17:37