# Newbie question on file reading

**URL:** <https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794>\
**Category:** Ruby\
**Created:** [August 24, 2010, 1:04pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794 "2010-08-24T13:04:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 1:04pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/1 "2010-08-24T13:04:07Z")

</div>

Hi,  
I have got the code to read a file line by line amd it works too but I  
don’t understand it.

fp = File.open(dataFile, “r”)  
fp.each\_line do |line|  
puts line  
end

My question is: the “open” method is not mentioned in the doc of File  
class  
[http://ruby-doc.org/core/classes/File.html](http://ruby-doc.org/core/classes/File.html)  
What type does it return?

My 2nd question is how can I read a file char by char. Basically the  
file doesn’t have line breaks.

Please help…

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 1:11pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/2 "2010-08-24T13:11:58Z")

</div>

I believe it comes from the IO class instead  
[http://ruby-doc.org/core/classes/IO.html](http://ruby-doc.org/core/classes/IO.html)

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 3:12pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/3 "2010-08-24T15:12:35Z")

</div>

2010/8/24 Peter H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I believe it comes from the IO class instead  
> [class IO - RDoc Documentation](http://ruby-doc.org/core/classes/IO.html)

Yes, this is true.

Rajarshi, you can make your life a bit simpler by doing

File.foreach(dataFile) do |line|  
puts line  
end

If you actually need to open the file and manipulate the File / IO  
object directly (e.g. because you want to rewind), you can use the  
block form of File.open (or IO.open):

File.open(dataFile, “r”) do |fp|  
fp.each\_line do |line|  
puts line  
end  
end

This ensures the file is properly closed which was not the case in  
your original example. You can find more at

[http://blog.rubybestpractices.com/posts/rklemme/001-Using\_blocks\_for\_Robustness.html](http://blog.rubybestpractices.com/posts/rklemme/001-Using_blocks_for_Robustness.html)

And if you want to know the internal workings you can look here

[http://blog.rubybestpractices.com/posts/rklemme/002\_Writing\_Block\_Methods.html](http://blog.rubybestpractices.com/posts/rklemme/002_Writing_Block_Methods.html)

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 3:42pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/4 "2010-08-24T15:42:27Z")

</div>

On Tue, Aug 24, 2010 at 4:34 PM, Rajarshi C.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> My 2nd question is how can I read a file char by char. Basically the  
> file doesn’t have line breaks.

How big is your file? IO.read(“/path/to/file”) will read the entire  
file into a string. If you really want to read it character by  
character

File.open(“/path/to/file”) do |f|  
while true do  
begin  
a = f.readchar  
# do something with a  
rescue EOFError  
break  
end  
end  
end

martin

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 4:11pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/5 "2010-08-24T16:11:09Z")

</div>

2010/8/24 Rajarshi C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Thank you, Robert.

Your welcome!

> The links were most helpful.

Good!

> I need to read char substrings from a file that has no line breaks in  
> it.

Note that you can use a different separator character:

File.foreach data\_file, “SEPARATOR” do |entry|  
puts entry  
end

The same works for File.each:

File.open… do |io|  
io.each “SEPARATOR” do |entry|  
…  
end  
end

> Is the code below the best way to do it?
> 
> File.foreach(dataFile) do |line|  
> puts line  
> end
> 
> Will the “line” var give the entire text in the file?

No, because this will try to load lines separated by \n. If you want  
the whole text of the file in one go you can do

contents = File.read data\_file

However, if the file is large, a blocked approach usually yields better  
results:

File.open data\_file do |io|  
buffer = “”

while io.read(1024, buffer)  
buffer.each\_char {|ch| p ch} # note, ch is really a String of length  
1  
end  
end

> Another question (this is posted on the link you gave)  
> Instead of doing File.foreach(dataFile) can I not do  
> IO.foreach(dataFile) do |line|?

Yes, File and IO are interchangeable here. Personally I prefer to use  
File when dealing with files just for documentation reasons.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 8:51pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/6 "2010-08-24T20:51:40Z")

</div>

Thank you, Martin and Robert

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 26, 2010, 10:44am UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/7 "2010-08-26T10:44:45Z")

</div>

In continuation with my questions about reading files from the file  
system…

It seems Dir[File.join(root, subDir, “\*”)] gives the full path name of  
all files in the sub directory

Can I modify the expression to give just the basename?

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 26, 2010, 10:58am UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/8 "2010-08-26T10:58:56Z")

</div>

2010/8/26 Rajarshi C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> In continuation with my questions about reading files from the file  
> system…
> 
> It seems Dir[File.join(root, subDir, “\*”)] gives the full path name of  
> all files in the sub directory
> 
> Can I modify the expression to give just the basename?

You can feed the result through #map and File.basename.

Cheers

robert

---

<div class="post-metadata">

**Author:** ![raj\_plays](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/838e76/32.png) [@raj\_plays](https://www.ruby-forum.com/u/raj_plays)\
**Post date:** [August 24, 2010, 3:41pm UTC](https://www.ruby-forum.com/t/newbie-question-on-file-reading/193794/9 "2010-08-24T15:41:26Z")

</div>

Thank you, Robert.  
The links were most helpful.

I need to read char substrings from a file that has no line breaks in  
it.  
Is the code below the best way to do it?

File.foreach(dataFile) do |line|  
puts line  
end

Will the “line” var give the entire text in the file?

Another question (this is posted on the link you gave)  
Instead of doing File.foreach(dataFile) can I not do  
IO.foreach(dataFile) do |line|?
