Is there a simpler way to do this?

J

Julian Leviston

Hi.

Just wondering if there's a simpler way to do this?

file = File.open("/usr/blah/1.txt") do | file |
while line = file.gets
the_string += line
end
end

In other words, open a file, read the contents into a string called
the_string

Thanks,
Julian.
 
J

James Edward Gray II

Hi.

Just wondering if there's a simpler way to do this?

file = File.open("/usr/blah/1.txt") do | file |
while line = file.gets
the_string += line
end
end

In other words, open a file, read the contents into a string called
the_string

file_contents = File.read("/usr/blah/1.txt")

James Edward Gray II
 
R

Robert Klemme

James said:
file_contents = File.read("/usr/blah/1.txt")

I was tempted to say "of course there is". It's so typical Ruby. :)

Btw, a remark to the OP's algorithm: IMHO this one is more efficient since
it does not create new String objects all the time:

file = File.open("/usr/blah/1.txt") do | file |
s = ""
while line = file.gets
s << line
end
s
end

Note also that you might get nil instead of the empty string in your
example if reading from an empty file (untested). But of course the one
liner is even more efficient. :)

Kind regards

robert
 
R

Robert Klemme

Zach said:
or, for two more characters shortened...

file_contents = IO.read("/usr/blah/1.txt")

One less...

file_contents = IO.read "/usr/blah/1.txt"

Of course, you can also truncate the variable name...
:)

robert
 
A

astrodean

I believe the following does it...

the_string=File.readlines("/usr/blah/1.txt"').join

Dean
 
A

Austin Ziegler

I believe the following does it...
the_string=3DFile.readlines("/usr/blah/1.txt"').join

Yes. But there's a problem with this -- it does more work than
necessary. The IO.read approach that is superior. However, I prefer:

contents =3D open(filename, "rb") { |f| f.read }

It's not quite as short as the IO.read approach, but it does two things for=
me:

1. It's safe for text or binary files on all platforms.
2. Because I'm using "open", if I do "require 'open-uri'", then
filename can also be a URL to a remoate location.

-austin
--=20
Austin Ziegler * (e-mail address removed)
* Alternate: (e-mail address removed)
 
F

Frank Wallingford

contents = open(filename, "rb") { |f| f.read }
It's safe for text or binary files on all platforms.

Is this true?

I couldn't find an answer in my quick glance over the standard library
docs, but I was under the impression that if you open a text file in
binary mode on some platforms that do text-mode translation for you
(Windows, for example), then you lose the translation. You may get
"\r\n" instead of "\n" for newlines (since that's how they exist in
binary on disk) and you may get "^Z" for the end of file marker.

I don't have a Windows machine to test with at the moment, but wouldn't
you get those extra \r and ^Z characters if you opened a text file in
binary mode?

-Frank
 
W

William James

Frank said:
Is this true?

I couldn't find an answer in my quick glance over the standard library
docs, but I was under the impression that if you open a text file in
binary mode on some platforms that do text-mode translation for you
(Windows, for example), then you lose the translation. You may get
"\r\n" instead of "\n" for newlines (since that's how they exist in
binary on disk) and you may get "^Z" for the end of file marker.

I don't have a Windows machine to test with at the moment, but wouldn't
you get those extra \r and ^Z characters if you opened a text file in
binary mode?

Just tried it. You get the \r characters but not the ^Z.
The end of file marker was only needed in the days when the messy-dos
filesystem didn't record the actual size of the file's contents.

After using the command above, you would split contents into
lines using
contents.split("\r\n")
 
W

William James

William said:
Just tried it. You get the \r characters but not the ^Z.
The end of file marker was only needed in the days when the messy-dos
filesystem didn't record the actual size of the file's contents.

After using the command above, you would split contents into
lines using
contents.split("\r\n")

Since this is supposed to work on all platforms:
contents.split(/(?:\r\n?)|\n/)
 
F

francisrammeloo

Since this is supposed to work on all platforms:
contents.split(/(?:\r\n?)|\n/)

Can you explain this pattern please ? I don't understand the "?:" part.

Francis
 
W

William James

Can you explain this pattern please ? I don't understand the "?:" part.

Francis

In a regexp, ( ) groups and captures; (?: ) groups without capturing.

But I made it too complex. The group isn't necessary:

irb(main):002:0> "a\nb\nc\r\nd\r\ne\rf".split(/\r\n?|\n/)
=> ["a", "b", "c", "d", "e", "f"]
 
S

Serpent

But my point is that reading text files in binary mode is bad. If you
want this to work on all platforms, open text files in text mode and
open binary files in binary mode.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top