Input/Output

For input/output there is a "File class" which inherits the "IO class". The File class has methods to interact with the file system and the IO class has methods to read and write files, but general usage statements as "print", "open", "close", are methods of the Object class.

There are also some useful iterators to deal with files.

A file is represented by a "File object", an instance of the "File class"; Ruby treats input and output as is done by the Unix system: files are simple streams of bytes; there are global variables referring to the default streams for reading, writing and writing error messages: "$stdin, $stderr, $stdin. These are instance of the IO class. There are also constants referring to these streams: STDIN, STDOUT, STDERR.

The function: open returns a File object:

f=open(filename,"access string")

If the filename begins with "|" it is a Unix named pipe; the access string defines the access method: read-only, read-write append etc.

"r:iso-8859-1" to read-only, for a specific encoding
"w+" read/write
"w" write only
"a" append to file, write only
"a+" append, read/write
"b" binary, to be added to the other codes: "wb" , "rb" ..

Some methods useful to read a file are listed in the following table; "f" is the file object:

f.close() closes the file
a=f.gets gets the next line
a=f.readline  
a=f.gets(10) gets 10 characters
a=f.gets("separator") gets a line, defined by an user-given line separator
a=gets next line from standard input
a=gets("separator")  
a=f.getc gets next character
a=f.getbyte gets next byte
f.lineno returns the current line number
f.lineno=10 set the initial value of the line counter (file position unchanged)
f.pos returns the file position (current byte)
f.path the complete file name
a=f.readlines returns an array with the file lines
a=f.readlines("s") lines array, a line separator is given
f.each {|a| ..} an iterator over the file lines
f.each_line {|a| ..} an iterator over the file lines
f.each("separator"){|a| ..} here a line separator is given
f.each_byte {|b| ..} an iterator over bytes
f.each_char {|b| ..} an iterator over characters

In the following table some methods of the File class, useful to deal with files:

File.exist?(filename) true if the file exists
File.file?(filename) tests if filename is a regular file
File.directory?(filename) tests if a directory
File.symlink?(filename) tests if filename is a symbolic link
, ,
File.size(filename) file size in bytes.
File.size?(filename) file size in bytes or nil if empty
File.zero?(filename) true if empty
, ,
File.readable?(filename) true if readable
File.writable?(filename) true if writable
File.executable?(filename) true if executable
File.world_readable?(filename) true if readable by everybody
File.world_writable?(filename) true if writable by everybody
, ,
File.ftype("/usr/bin/ruby") type of the file: "file", "directory", "link"
, ,
File.rename("newname", "oldname") renames a file
File.symlink("name", "link") makes a link
File.delete("test2") deletes a file
File.utime(atime, mtime, filename) changes access and modification time
File.chmod(0600, f) sets unix file permissions (octal argument)
. .
File.read("filename") reads and return the entire file as a string
File.read("filename", 4, 2) returns 4 bytes starting at byte 2
File.read("filename", nil, 6) returns from byte 6 to the end-of-file
linee = File.readlines("filename") return an array with the file lines
File.foreach("filename") { } block looping on lines

The following examples show how the functions putc, puts, print, write can be used for output:

o = STDOUT

o.putc(65)         # writes the single byte 65 (capital A)
o.putc("B")        # writes the single byte 66 (capital B)

o << x             # print 'x'
o << x << y        # print 'x' and 'y'

o.print s

o.printf fmt,*args # the printf function of C

o.puts             # prints a newline
o.puts x           # prints 'x', then a newline

o.write s          # doesn't print a final newline

The following examples show how a specific position in a file can be accessed (random access):

f = File.open("test.txt")

f.pos        #  returns the current byte, same as: 'f.tell'
f.pos = 10   #  set the position counter to 10

f.rewind     #  goes to the beginning of the file

f.seek(10)                # go to byte 10, same as: 'f.seek(10, IO::SEEK_SET)'
f.seek(10, IO::SEEK_CUR)  # skips 10 bytes from current position

f.eof?                    # tests if at end of file
f.closed?                 # tests if the file has been closed
f.tty?                    # tests if the stream is the interactive console

Ruby doesn't write immediately to e file when a print statement is issued, but use memory buffers for a temporary storage to optimize the writing times; the operating system uses its own buffers too: the Ruby output is buffered by Ruby, then given to the system and stored again; the writing is not a real-time process; but some Ruby functions can control the buffering:

out=File.open('filename')
out.write("abcd")

out.flush         # flush the Ruby output buffer for this stream

  # to set the buffer mode:

out.sync = true   # buffers are flushed after every write
out.sync = false  # output is buffered by Ruby
out.sync          # show the current buffer mode
out.fsync         # flush the system buffers (not possible for some systems)