# Newbie question on file reading

**URL:** https://rubytalk.org/t/newbie-question-on-file-reading/59763
**Category:** ruby-talk
**Created:** [24 August 2010 11:04 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763 "2010-08-24T11:04:12Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Rajarshi\_Chakravarty](https://avatars.discourse-cdn.com/v4/letter/r/59ef9b/32.png) [@Rajarshi\_Chakravarty](https://rubytalk.org/u/Rajarshi_Chakravarty)
#### Post date: [24 August 2010 11:04 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/1 "2010-08-24T11:04:12Z")

</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..

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

### Author: ![Peter\_Hickman2](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/peter_hickman2/32/1832_2.png) [@Peter\_Hickman2](https://rubytalk.org/u/Peter_Hickman2)
#### Post date: [24 August 2010 11:11 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/2 "2010-08-24T11:11:03Z")

</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: ![Martin\_DeMello](https://avatars.discourse-cdn.com/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://rubytalk.org/u/Martin_DeMello)
#### Post date: [24 August 2010 13:39 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/3 "2010-08-24T13:39:17Z")

</div>

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|  
&nbsp;&nbsp;while true do  
&nbsp;&nbsp;&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a = f.readchar  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# do something with a  
&nbsp;&nbsp;&nbsp;&nbsp;rescue EOFError  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

martin

> **···**
>
> On Tue, Aug 24, 2010 at 4:34 PM, Rajarshi Chakravarty \<raj\_plays@yahoo.com\> wrote:
> 
> > My 2nd question is how can I read a file char by char. Basically the  
> > file doesn't have line breaks.

---

<div class="post-metadata">

### Author: ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)
#### Post date: [24 August 2010 13:12 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/4 "2010-08-24T13:12:09Z")

</div>

Yes, this is true.

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

File.foreach(dataFile) do |line|  
&nbsp;&nbsp;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|  
&nbsp;&nbsp;fp.each\_line do |line|  
&nbsp;&nbsp;&nbsp;&nbsp;puts line  
&nbsp;&nbsp;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

> **···**
>
> 2010/8/24 Peter Hickman \<peterhickman386@googlemail.com\>:
> 
> > I believe it comes from the IO class instead  
> > [class IO - RDoc Documentation](http://ruby-doc.org/core/classes/IO.html)
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

### Author: ![Rajarshi\_Chakravarty](https://avatars.discourse-cdn.com/v4/letter/r/59ef9b/32.png) [@Rajarshi\_Chakravarty](https://rubytalk.org/u/Rajarshi_Chakravarty)
#### Post date: [24 August 2010 13:41 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/5 "2010-08-24T13:41:28Z")

</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|  
&nbsp;&nbsp;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|?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

### Author: ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)
#### Post date: [24 August 2010 14:08 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/6 "2010-08-24T14:08:22Z")

</div>

> 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|  
&nbsp;&nbsp;puts entry  
end

The same works for File.each:

File.open... do |io|  
&nbsp;&nbsp;io.each "SEPARATOR" do |entry|  
&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;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|  
&nbsp;&nbsp;buffer = ""

&nbsp;&nbsp;while io.read(1024, buffer)  
&nbsp;&nbsp;&nbsp;&nbsp;buffer.each\_char {|ch| p ch} # note, ch is really a String of length 1  
&nbsp;&nbsp;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

> **···**
>
> 2010/8/24 Rajarshi Chakravarty \<raj\_plays@yahoo.com\>:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

### Author: ![Rajarshi\_Chakravarty](https://avatars.discourse-cdn.com/v4/letter/r/59ef9b/32.png) [@Rajarshi\_Chakravarty](https://rubytalk.org/u/Rajarshi_Chakravarty)
#### Post date: [24 August 2010 18:53 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/7 "2010-08-24T18:53:38Z")

</div>

Thank you, Martin and Robert

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

### Author: ![Rajarshi\_Chakravarty](https://avatars.discourse-cdn.com/v4/letter/r/59ef9b/32.png) [@Rajarshi\_Chakravarty](https://rubytalk.org/u/Rajarshi_Chakravarty)
#### Post date: [26 August 2010 08:44 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/8 "2010-08-26T08:44:48Z")

</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?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

### Author: ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)
#### Post date: [26 August 2010 08:58 UTC](https://rubytalk.org/t/newbie-question-on-file-reading/59763/9 "2010-08-26T08:58:29Z")

</div>

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

Cheers

robert

> **···**
>
> 2010/8/26 Rajarshi Chakravarty \<raj\_plays@yahoo.com\>:
> 
> > 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?
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)
