11.2 File Access: Reading and Writing

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.

Table 11-1. Some file access modes

Mode

Description

r

Read access only. Points to start of the file. This is the default, but it is good programming style to specify it anyway.

w

Write access only. Points to the beginning of the file that will overwrite the file’s content if it already exists.

Gem of Wisdom

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.

Example 11-1. Sample code for file reading
     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.

Example 11-2. File read/write example
     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.

11.2.1 File Reader Class

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.

Example 11-3. FileReader class
     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.

11.2.2 FileWriter Class

The class in Example 11-4 encapsulates writing to and closing a file.

Example 11-4. FileWriter class
     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.

11.2.3 File Reader/Writer Example

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.

Example 11-5. FileReader/FileWriter example
     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.

Example 11-6. Sample input file
    Hello world!
    A mighty fine day for ruby programming!
    Computer Science is the best!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.236.27