Skip to content

End of Life Ruby 3.0 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →

class method

CSV.foreach

foreach(path, mode='r', **options) {|row| ... )
foreach(io, mode='r', **options {|row| ... )
foreach(path, mode='r', headers: ..., **options) {|row| ... )
foreach(io, mode='r', headers: ..., **options {|row| ... )
foreach(path, mode='r', **options) → new_enumerator
foreach(io, mode='r', **options → new_enumerator

Calls the block with each row read from source path or io.

  • Argument path, if given, must be the path to a file.

  • Argument io should be an IO object that is:

    • Open for reading; on return, the IO object will be closed.

    • Positioned at the beginning. To position at the end, for appending, use method CSV.generate. For any other positioning, pass a preset StringIO object instead.

  • Argument mode, if given, must be a File mode See Open Mode.

  • Arguments **options must be keyword options. See Options for Parsing.

  • This method optionally accepts an additional :encoding option that you can use to specify the Encoding of the data read from path or io. You must provide this unless your data is in the encoding given by Encoding::default_external. Parsing will use this to determine how to parse the data. You may provide a second Encoding to have the data transcoded as it is read. For example,

    encoding: 'UTF-32BE:UTF-8'

    would read UTF-32BE data from the file but transcode it to UTF-8 before parsing.

Without Option headers

Without option headers, returns each row as an Array object.

These examples assume prior execution of:

Example
string = "foo,0\nbar,1\nbaz,2\n"
path = 't.csv'
File.write(path, string)

Read rows from a file at path:

Example
CSV.foreach(path) {|row| p row }

Output:

Example
["foo", "0"]
["bar", "1"]
["baz", "2"]

Read rows from an IO object:

Example
File.open(path) do |file|
  CSV.foreach(file) {|row| p row }
end

Output:

Example
["foo", "0"]
["bar", "1"]
["baz", "2"]

Returns a new Enumerator if no block given:

Example
CSV.foreach(path) # => #<Enumerator: CSV:foreach("t.csv", "r")>
CSV.foreach(File.open(path)) # => #<Enumerator: CSV:foreach(#<File:t.csv>, "r")>

Issues a warning if an encoding is unsupported:

Example
CSV.foreach(File.open(path), encoding: 'foo:bar') {|row| }

Output:

warning: Unsupported encoding foo ignored
warning: Unsupported encoding bar ignored
With Option headers

With option headers, returns each row as a CSV::Row object.

These examples assume prior execution of:

Example
string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n"
path = 't.csv'
File.write(path, string)

Read rows from a file at path:

Example
CSV.foreach(path, headers: true) {|row| p row }

Output:

Example
#<CSV::Row "Name":"foo" "Count":"0">
#<CSV::Row "Name":"bar" "Count":"1">
#<CSV::Row "Name":"baz" "Count":"2">

Read rows from an IO object:

Example
File.open(path) do |file|
  CSV.foreach(file, headers: true) {|row| p row }
end

Output:

Example
#<CSV::Row "Name":"foo" "Count":"0">
#<CSV::Row "Name":"bar" "Count":"1">
#<CSV::Row "Name":"baz" "Count":"2">

Raises an exception if path is a String, but not the path to a readable file:

Example
# Raises Errno::ENOENT (No such file or directory @ rb_sysopen - nosuch.csv):
CSV.foreach('nosuch.csv') {|row| }

Raises an exception if io is an IO object, but not open for reading:

Example
io = File.open(path, 'w') {|row| }
# Raises TypeError (no implicit conversion of nil into String):
CSV.foreach(io) {|row| }

Raises an exception if mode is invalid:

Example
# Raises ArgumentError (invalid access mode nosuch):
CSV.foreach(path, 'nosuch') {|row| }
See also .filter .generate .generate_line also in 3.3 · 3.2 · 3.1