To access files, the built-in Ruby File
class is used. This class contains multiple
methods. We use the following: open
,
close
, gets
, and puts
. The method File.open
instantiates a new object that enables
Ruby to read from or write to an existing or new file. The object returned
by File.open
can then be used by Ruby
to access the file. The following code shows how to open a file:
myfile
=
File
.
open
(
file_name
,
access_mode
)
The myfile
variable is a File
object that can now be used to interact
with the file’s contents, depending on what access mode is used. Note that
file name
and access mode
are strings. The variable file_name
is a representation of a path to a
file, such as /home/ruby/file.txt. The myfile
variable in our program is local to only
our program. Two of the most basic access modes and what they do are shown
in Table 11-1.
Mode |
Description |
|
Read access only. Points to start of the file. This is the default, but it is good programming style to specify it anyway. |
|
Write access only. Points to the beginning of the file that will overwrite the file’s content if it already exists. |
Files provide access to data resident in the computer system’s long-term memory. Storage in long-term memory, such as disks, provides data resiliency, namely, permanence. That is, disks work even without power, so they store things far longer than the internal random access memory, which works only if the power is on.
To read a line of characters from a file, call the gets
method on the myfile
object. When the gets
method is called, it reads characters until
it reaches a newline character (
),
and then it returns what it read. The File
object keeps track of what has been read
in, so each successive call to gets
will always return the next line, until it reaches the end of the file and
returns nil
. nil
has the logical truth value of false
. Every other value returned by gets
has the logical value of true
. Consider the code provided in Example 11-1, which reads in a file foo.txt and then prints it out.
1
myfile
=
File
.
open
(
"foo.txt"
,
"r"
)
2
whole_file
=
""
3
4
while
(
input_line
=
myfile
.
gets
)
5
whole_file
+=
input_line
6
end
7
8
puts
"Contents of input file:"
9
puts
whole_file
10
myfile
.
close
()
Line 1 opens foo.txt for read access.
Line 2 instantiates an empty string variable, whole_file
, which will be used to store the
file to display.
Lines 4–6 contain a loop that reads the file into input_line
, one line at a time, and appends
each line into whole_file
.
Line 9 prints out the file.
Sequentially writing to a file is similar to sequentially reading
from a file. Instead of opening the file in read mode, the file needs to
be opened with w
for writing access. To
write text to a file, use the local variable myfile
to call the puts
method:
myfile
.
puts
(
"text goes here!"
)
The code shown in Example 11-2 opens a file for write access, accepts user input, and writes that input to the file. It will then close the file, reopen it, and print the contents to verify correctness.
1
file_a
=
File
.
open
(
"bar.txt"
,
"w"
)
2
3
puts
"Please enter a line of text"
4
line
=
gets
()
5
file_a
.
puts
(
line
)
6
file_a
.
close
()
7
8
file_b
=
File
.
open
(
"bar.txt"
,
"r"
)
9
puts
"Contents of file:"
10
puts
file_b
.
gets
()
11
file_b
.
close
()
Line 1 opens bar.txt as
file object file_a
with write
access.
Lines 3–4 take text input from the user.
Line 5 writes the user input into "bar.txt"
.
Line 6 closes the File
object
file_a
(this saves the text inside
it by closing the file and preventing further access to it).
Line 8 instantiates a new File
object file_b
. This object will be used for the
purpose of reading the content of bar.txt. Note the file access mode r
.
Line 10 outputs the contents of the newly created file to the console, illustrating that the code in Example 11-2 behaves in the desired fashion.
We will now define two classes that encapsulate reading in a file and writing out a file. Then we will use the two classes to create a file copy program that will read text from a file and then copy the text into a new file.
The class presented in Example 11-3 encapsulates reading and displaying a file.
1
class
FileReader
2
3
def
initialize
(
file_name
)
4
@file
=
File
.
open
(
file_name
,
"r"
)
5
end
6
7
def
read_file
8
whole_file
=
""
9
while
(
input_line
=
@file
.
gets
)
10
whole_file
+=
input_line
11
end
12
13
return
whole_file
14
end
15
16
def
display
17
puts
"Contents of input file:"
18
puts
read_file
19
end
20
21
def
close
22
@file
.
close
()
23
end
24
end
Lines 3–5 define the constructor. The variable @file
references the File
object that has been opened.
Line 4 opens the file for the purpose of reading the contents.
The r
indicates that this file is
to be open for reading.
Lines 7–14 define the read
file
method. This method incorporates a basic loop that
goes through a given file using gets
for the purpose of reading one line
at a time.
Line 10 appends (adds to the end of the string) to whole_file
the contents of the currently
read line of the file.
Line 13 returns the contents of the file that is now stored in
whole_file
.
Lines 16–19 define a display method that outputs the contents of the file.
Lines 21–23 define a close method that closes the opened file,
@file
.
The class in Example 11-4 encapsulates writing to and closing a file.
1
class
FileWriter
2
3
def
initialize
(
file_name
)
4
@file
=
File
.
open
(
file_name
,
"w"
)
5
end
6
7
def
write_line
(
output_line
)
8
@file
.
puts
(
output_line
)
9
end
10
11
def
close
12
@file
.
close
()
13
end
14
end
Lines 3–5 define the constructor.
Line 4 opens the file file_name
using w
for write access mode.
Lines 7–9 define the write_line
method, which outputs a single
line, output_line
, to a file associated
with the FileWriter
object.
Line 8 makes use of the puts
method to output the contents of a
given output_line
to the file
referenced by @file
.
Lines 11–13 close the file. This ensures that all the data that have been written to the file are actually written to it. That is, data that are temporarily buffered in intermediate storage are actually written to secondary (permanent) storage. Buffering is commonly used to reduce output writing delays.
The above use of buffers may seem obscure for a reader who is not
familiar with the actual mechanisms employed in writing a file. In
reality, the puts
method does not actually write to a
file; it actually fills a holding area commonly referred to as a
buffer.
The code in Example 11-5
will read in a file and write the contents out to a new file. This code
assumes you have written out the class definitions for FileReader
and FileWriter
given in the preceding section as files named file_reader.rb and file_writer.rb.
1
require_relative
"file_reader.rb"
2
require_relative
"file_writer.rb"
3
4
fr
=
FileReader
.
new
(
"input.txt"
)
5
fw
=
FileWriter
.
new
(
"output.txt"
)
6
7
input
=
fr
.
read_file
()
8
fw
.
write_line
(
input
)
9
10
fw
.
close
()
11
fr
.
close
()
Lines 1 and 2 import the class definitions of FileReader
and FileWriter
.
Lines 4 and 5 create instances of our two classes, the first for input, the second for output.
Line 7 reads the file into a string called input
.
Line 8 writes the string input
out to the file held by the instance
of FileWriter
.
Lines 10 and 11 close both of the open files.
To verify that the code presented in Example 11-5 works correctly, use the input text file with the content shown in Example 11-6. After running Example 11-5’s code with the input from Example 11-6, ensure that output.txt is the same as input.txt.
3.149.236.27