Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read a file in chunks in Ruby

Tags:

ruby

I need to read a file in MB chunks, is there a cleaner way to do this in Ruby:

FILENAME="d:\\tmp\\file.bin"
MEGABYTE = 1024*1024
size = File.size(FILENAME)
open(FILENAME, "rb") do |io| 
  read = 0
  while read < size
    left = (size - read)
    cur = left < MEGABYTE ? left : MEGABYTE
    data = io.read(cur)
    read += data.size
    puts "READ #{cur} bytes" #yield data
  end
end
like image 955
teleball Avatar asked Nov 05 '09 17:11

teleball


3 Answers

Adapted from the Ruby Cookbook page 204:

FILENAME = "d:\\tmp\\file.bin"
MEGABYTE = 1024 * 1024

class File
  def each_chunk(chunk_size = MEGABYTE)
    yield read(chunk_size) until eof?
  end
end

open(FILENAME, "rb") do |f|
  f.each_chunk { |chunk| puts chunk }
end

Disclaimer: I'm a ruby newbie and haven't tested this.

like image 112
mbarkhau Avatar answered Oct 23 '22 20:10

mbarkhau


Alternatively, if you don't want to monkeypatch File:

until my_file.eof?
  do_something_with( my_file.read( bytes ) )
end

For example, streaming an uploaded tempfile into a new file:

# tempfile is a File instance
File.open( new_file, 'wb' ) do |f|
  # Read in small 65k chunks to limit memory usage
  f.write(tempfile.read(2**16)) until tempfile.eof?
end
like image 17
Phrogz Avatar answered Oct 23 '22 20:10

Phrogz


You can use IO#each(sep, limit), and set sep to nil or empty string, for example:

chunk_size = 1024
File.open('/path/to/file.txt').each(nil, chunk_size) do |chunk|
  puts chunk
end
like image 5
Weihang Jian Avatar answered Oct 23 '22 20:10

Weihang Jian