Class: Redisk::IO
- Inherits:
-
Object
- Object
- Redisk::IO
- Extended by:
- Helper
- Includes:
- Enumerable, Helper
- Defined in:
- lib/redisk/io.rb
Defined Under Namespace
Classes: EOFError, IOError, NotImplementedError
Constant Summary collapse
- SEEK_SET =
0
- SEEK_CUR =
1
- SEEK_END =
2
Instance Attribute Summary collapse
-
#_ ⇒ Object
readonly
Returns the value of attribute _.
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
- .all ⇒ Object
- .dir ⇒ Object
-
.foreach(name, &block) ⇒ Object
Executes the block for every line in the named I/O port, where lines are separated by sep_string.
-
.from_file(name, file) ⇒ Object
Reads the contents of file into the IO.
- .list_key(name) ⇒ Object
-
.open(name, mode = 'r') ⇒ Object
With no associated block, open is a synonym for IO::new.
-
.pipe ⇒ Object
IO.pipe → array Creates a pair of pipe endpoints (connected to each other) and returns them as a two-element array of IO objects: [ read_file, write_file ].
-
.read(name, length = nil, offset = nil) ⇒ Object
Opens the file, optionally seeks to the given offset, then returns length bytes (defaulting to the rest of the file).
-
.read_lines(name, length = nil, offset = nil) ⇒ Object
Works similarly to IO.read, but operates on lines instead of bytes.
-
.readlines(name) ⇒ Object
Reads the entire file specified by name as individual lines, and returns those lines in an array.
-
.select(name) ⇒ Object
IO.select(read_array [, write_array [, error_array [, timeout]]] ) => array or nil See Kernel#select.
-
.sysopen(name) ⇒ Object
IO.sysopen(path, [mode, [perm]]) => fixnum Opens the given path, returning the underlying file descriptor as a Fixnum.
-
.to_file(name, file) ⇒ Object
Writes the contents of IO into file.
-
.unlink(name) ⇒ Object
Removes all references to the io at name.
Instance Method Summary collapse
-
#<<(text) ⇒ Object
String Output—Writes obj to ios.
-
#binmode ⇒ Object
ios.binmode => ios Puts ios into binary mode.
-
#close ⇒ Object
ios.close => nil Closes ios and flushes any pending writes to the operating system.
-
#close_read ⇒ Object
ios.close_read => nil Closes the read end of a duplex I/O stream (i.e., one that contains both a read and a write stream, such as a pipe).
-
#close_write ⇒ Object
ios.close_write => nil Closes the write end of a duplex I/O stream (i.e., one that contains both a read and a write stream, such as a pipe).
-
#closed? ⇒ Boolean
ios.closed? => true or false Returns true if ios is completely closed (for duplex streams, both reader and writer), false otherwise.
- #dir ⇒ Object
-
#each(&block) ⇒ Object
(also: #each_line)
ios.each(sep_string=$/) {|line| block } => ios ios.each_line(sep_string=$/) {|line| block } => ios Executes the block for every line in ios, where lines are separated by sep_string.
-
#each_byte ⇒ Object
ios.each_byte {|byte| block } => nil Calls the given block once for each byte (0..255) in ios, passing the byte as an argument.
-
#eof ⇒ Object
(also: #eof?)
ios.eof => true or false ios.eof? => true or false Returns true if ios is at end of file that means there are no more data to read.
-
#fcntl(integer_cmd, arg) ⇒ Object
ios.fcntl(integer_cmd, arg) => integer Provides a mechanism for issuing low-level commands to control or query file-oriented I/O streams.
-
#fileno ⇒ Object
(also: #to_i)
ios.fileno => fixnum ios.to_i => fixnum Returns an integer representing the numeric file descriptor for ios.
-
#flush ⇒ Object
ios.flush => ios Flushes any buffered data within ios to the underlying operating system (note that this is Ruby internal buffering only; the OS may buffer the data as well).
-
#from_file(file) ⇒ Object
Reads the contents of file into the IO.
-
#fsync ⇒ Object
ios.fsync => 0 or nil Immediately writes all buffered data in ios to disk.
-
#getc ⇒ Object
ios.getc => fixnum or nil Gets the next 8-bit byte (0..255) from ios.
-
#gets ⇒ Object
ios.gets(sep_string=$/) => string or nil Reads the next “line’’ from the I/O stream; lines are separated by sep_string.
-
#initialize(name, mode = 'r') ⇒ IO
(also: #for_fd)
constructor
A new instance of IO.
-
#inspect ⇒ Object
(also: #to_s)
Return a string describing this IO object.
-
#ioctl(integer_cmd, arg) ⇒ Object
ios.ioctl(integer_cmd, arg) => integer Provides a mechanism for issuing low-level commands to control or query I/O devices.
-
#isatty ⇒ Object
ios.isatty => true or false ios.tty? => true or false Returns true if ios is associated with a terminal device (tty), false otherwise.
-
#length ⇒ Object
(also: #lines)
the number of lines in the current list/file.
-
#lineno ⇒ Object
ios.lineno => integer Returns the current line number in ios.
-
#lineno=(num) ⇒ Object
ios.lineno = integer => integer Manually sets the current line number to the given value.
- #list_key ⇒ Object
- #open?(stream = nil) ⇒ Boolean
-
#pid ⇒ Object
ios.pid => fixnum Returns the process ID of a child process associated with ios.
-
#pos ⇒ Object
(also: #tell)
ios.pos => integer ios.tell => integer Returns the current offset (in bytes) of ios.
-
#pos=(num) ⇒ Object
ios.pos = integer => integer Seeks to the given position (in bytes) in ios.
-
#print(*args) ⇒ Object
ios.print() => nil ios.print(obj, …) => nil Writes the given object(s) to ios.
-
#printf(format_string, *args) ⇒ Object
ios.printf(format_string [, obj, …] ) => nil Formats and writes to ios, converting parameters under control of the format string.
-
#putc(obj) ⇒ Object
ios.putc(obj) => obj If obj is Numeric, write the character whose code is obj, otherwise write the first character of the string representation of obj to ios.
-
#puts(*args) ⇒ Object
ios.puts(obj, …) => nil Writes the given objects to ios as with IO#print.
-
#read(length = nil, buffer = nil) ⇒ Object
ios.read([length [, buffer]]) => string, buffer, or nil Reads at most length bytes from the I/O stream, or to the end of file if length is omitted or is nil.
-
#read_nonblock ⇒ Object
ios.read_nonblock(maxlen) => string ios.read_nonblock(maxlen, outbuf) => outbuf Reads at most maxlen bytes from ios using read(2) system call after O_NONBLOCK is set for the underlying file descriptor.
-
#readbytes(n) ⇒ Object
readbytes(n) Reads exactly n bytes.
-
#readchar ⇒ Object
ios.readchar => fixnum Reads a character as with IO#getc, but raises an EOFError on end of file.
-
#readline ⇒ Object
ios.readline(sep_string=$/) => string Reads a line as with IO#gets, but raises an EOFError on end of file.
-
#readlines ⇒ Object
ios.readlines(sep_string=$/) => array Reads all of the lines in ios, and returns them in anArray.
-
#readpartial ⇒ Object
ios.readpartial(maxlen) => string ios.readpartial(maxlen, outbuf) => outbuf Reads at most maxlen bytes from the I/O stream.
-
#reopen ⇒ Object
ios.reopen(other_IO) => ios ios.reopen(path, mode_str) => ios Reassociates ios with the I/O stream given in other_IO or to a new stream opened on path.
-
#rewind ⇒ Object
ios.rewind => 0 Positions ios to the beginning of input, resetting lineno to zero.
-
#scanf ⇒ Object
scanf(str,&b) The trick here is doing a match where you grab one line of input at a time.
-
#seek(offset, whence = SEEK_SET) ⇒ Object
ios.seek(amount, whence=SEEK_SET) → 0 Seeks to a given offset anInteger in the stream according to the value of whence:.
-
#seek_lines(offset, whence = SEEK_SET) ⇒ Object
works just like seek, but seeks by lineno instead of pos.
-
#size ⇒ Object
the estimated size in bytes of the current file.
-
#stat ⇒ Object
ios.stat => stat Returns status information for ios as an object of type File::Stat.
-
#sync ⇒ Object
ios.sync => true or false Returns the current “sync mode’’ of ios.
-
#sync=(setting) ⇒ Object
ios.sync = boolean => boolean Sets the “sync mode’’ to true or false.
-
#sysread(num) ⇒ Object
ios.sysread(integer ) => string Reads integer bytes from ios using a low-level read and returns them as a string.
-
#sysseek(offset, whence = SEEK_SET) ⇒ Object
ios.sysseek(offset, whence=SEEK_SET) => integer Seeks to a given offset in the stream according to the value of whence (see IO#seek for values of whence).
-
#syswrite(string) ⇒ Object
ios.syswrite(string) => integer Writes the given string to ios using a low-level write.
-
#to_file(file) ⇒ Object
Writes the contents of IO into file.
- #true_size ⇒ Object
-
#truncate(size = 0) ⇒ Object
truncate the IO to size, taking only the last [size] lines.
-
#ungetc(integer) ⇒ Object
ios.ungetc(integer) => nil Pushes back one character (passed as a parameter) onto ios, such that a subsequent buffered read will return it.
-
#unlink ⇒ Object
(also: #delete)
Removes all references to the IO and closes it for reading and writing.
-
#write(string) ⇒ Object
ios.write(string) => integer Writes the given string to ios.
-
#write_nonblock(string) ⇒ Object
ios.write_nonblock(string) => integer Writes the given string to ios using write(2) system call after O_NONBLOCK is set for the underlying file descriptor.
Methods included from Helper
Constructor Details
#initialize(name, mode = 'r') ⇒ IO Also known as: for_fd
Returns a new instance of IO.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/redisk/io.rb', line 13 def initialize(name, mode = 'r') @name = name @mode = mode # we're going to just ignore this for now @read_open = true @write_open = true @write_buffer = nil @read_buffer = nil @sync = false @pos = 0 @lineno = 0 @size = stat.size > 0 ? stat.size : true_size # add io to the list of ios redis.sadd dir, name rewind end |
Instance Attribute Details
#_ ⇒ Object (readonly)
Returns the value of attribute _.
11 12 13 |
# File 'lib/redisk/io.rb', line 11 def _ @_ end |
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
11 12 13 |
# File 'lib/redisk/io.rb', line 11 def mode @mode end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
11 12 13 |
# File 'lib/redisk/io.rb', line 11 def name @name end |
Class Method Details
.all ⇒ Object
38 39 40 |
# File 'lib/redisk/io.rb', line 38 def self.all redis.smembers dir end |
.dir ⇒ Object
42 43 44 |
# File 'lib/redisk/io.rb', line 42 def self.dir "__ios__" end |
.foreach(name, &block) ⇒ Object
Executes the block for every line in the named I/O port, where lines are separated by sep_string.
IO.foreach("testfile") {|x| print "GOT ", x }
produces:
GOT This is line one
GOT This is line two
GOT This is line three
GOT And so on...
60 61 62 63 64 |
# File 'lib/redisk/io.rb', line 60 def self.foreach(name, &block) io = new(name) io.each_line(&block) io.close end |
.from_file(name, file) ⇒ Object
Reads the contents of file into the IO. If file is not a File its taken as a path and passed to File.open
171 172 173 174 175 |
# File 'lib/redisk/io.rb', line 171 def self.from_file(name, file) io = new(name) io.from_file(file) io end |
.list_key(name) ⇒ Object
30 31 32 |
# File 'lib/redisk/io.rb', line 30 def self.list_key(name) "#{name}:_list" end |
.open(name, mode = 'r') ⇒ Object
With no associated block, open is a synonym for IO::new. If the optional code block is given, it will be passed io as an argument, and the IO object will automatically be closed when the block terminates. In this instance, IO::open returns the value of the block.
70 71 72 73 74 75 |
# File 'lib/redisk/io.rb', line 70 def self.open(name, mode = 'r') io = new(name, mode) returned = block_given? ? yield(io) : io io.close returned end |
.pipe ⇒ Object
IO.pipe → array Creates a pair of pipe endpoints (connected to each other) and returns them as a two-element array of IO objects: [ read_file, write_file ]. Not available on all platforms.
In the example below, the two processes close the ends of the pipe that they are not using. This is not just a cosmetic nicety. The read end of a pipe will not generate an end of file condition if there are any writers with the pipe still open. In the case of the parent process, the rd.read will never return if it does not first issue a wr.close.
rd, wr = IO.pipe
if fork
wr.close
puts "Parent got: <#{rd.read}>"
rd.close
Process.wait
else
rd.close
puts "Sending message to parent"
wr.write "Hi Dad"
wr.close
end
produces:
Sending message to parent
Parent got: <Hi Dad>
105 106 107 |
# File 'lib/redisk/io.rb', line 105 def self.pipe raise NotImplementedError, ".pipe is not implemented" end |
.read(name, length = nil, offset = nil) ⇒ Object
Opens the file, optionally seeks to the given offset, then returns length bytes (defaulting to the rest of the file). read ensures the file is closed before returning.
IO.read("testfile") #=> "This is line one\nThis is line
twonThis is line threenAnd so on…n“
IO.read("testfile", 20) #=> "This is line one\nThi"
IO.read("testfile", 20, 10) #=> "ne one\nThis is line "
117 118 119 120 121 122 123 |
# File 'lib/redisk/io.rb', line 117 def self.read(name, length = nil, offset = nil) io = new(name) io.seek(offset) if offset returned = io.read(length) io.close returned end |
.read_lines(name, length = nil, offset = nil) ⇒ Object
Works similarly to IO.read, but operates on lines instead of bytes
126 127 128 129 130 131 |
# File 'lib/redisk/io.rb', line 126 def self.read_lines(name, length = nil, offset = nil) start_i = offset || 0 end_i = length ? start_i + (length - 1) : -1 values = redis.lrange(list_key(name), start_i, end_i) values.join end |
.readlines(name) ⇒ Object
Reads the entire file specified by name as individual lines, and returns those lines in an array. Lines are separated by sep_string.
a = IO.readlines("testfile")
a[0] #=> "This is line one\n"
138 139 140 |
# File 'lib/redisk/io.rb', line 138 def self.readlines(name) redis.lrange(list_key(name), 0, -1) || [] end |
.select(name) ⇒ Object
IO.select(read_array [, write_array [, error_array
- , timeout]]
-
) => array or nil
See Kernel#select.
147 148 149 |
# File 'lib/redisk/io.rb', line 147 def self.select(name) raise NotImplementedError, ".select is not implemented" end |
.sysopen(name) ⇒ Object
IO.sysopen(path, [mode, [perm]]) => fixnum Opens the given path, returning the underlying file descriptor as a Fixnum.
IO.sysopen("testfile") #=> 3
156 157 158 |
# File 'lib/redisk/io.rb', line 156 def self.sysopen(name) raise NotImplementedError, ".sysopen is not implemented" end |
.to_file(name, file) ⇒ Object
Writes the contents of IO into file. If file is not a File its taken as a path and passed to File.open
179 180 181 182 183 |
# File 'lib/redisk/io.rb', line 179 def self.to_file(name, file) io = new(name) io.to_file(file) io end |
.unlink(name) ⇒ Object
Removes all references to the io at name
161 162 163 164 165 166 167 |
# File 'lib/redisk/io.rb', line 161 def self.unlink(name) redis.keys("#{name}:*").each do |key| redis.del key.gsub('redisk:','') end redis.srem dir, name nil end |
Instance Method Details
#<<(text) ⇒ Object
String Output—Writes obj to ios. obj will be converted to a string using to_s.
$stdout << "Hello " << "world!\n"
produces:
Hello world!
192 193 194 195 196 197 |
# File 'lib/redisk/io.rb', line 192 def <<(text) @write_buffer ||= '' @write_buffer << text flush if sync @write_buffer end |
#binmode ⇒ Object
ios.binmode => ios Puts ios into binary mode. This is useful only in MS-DOS/Windows environments. Once a stream is in binary mode, it cannot be reset to nonbinary mode.
204 |
# File 'lib/redisk/io.rb', line 204 def binmode; end |
#close ⇒ Object
ios.close => nil Closes ios and flushes any pending writes to the operating system. The stream is unavailable for any further data operations; an IOError is raised if such an attempt is made. I/O streams are automatically closed when they are claimed by the garbage collector.
If ios is opened by IO.popen, close sets $?.
213 214 215 216 217 |
# File 'lib/redisk/io.rb', line 213 def close flush close_read close_write end |
#close_read ⇒ Object
ios.close_read => nil Closes the read end of a duplex I/O stream (i.e., one that contains both a read and a write stream, such as a pipe). Will raise an IOError if the stream is not duplexed.
f = IO.popen("/bin/sh","r+")
f.close_read
f.readlines
produces:
prog.rb:3:in `readlines': not opened for reading (IOError)
from prog.rb:3
231 232 233 234 |
# File 'lib/redisk/io.rb', line 231 def close_read @read_open = false nil end |
#close_write ⇒ Object
ios.close_write => nil Closes the write end of a duplex I/O stream (i.e., one that contains both a read and a write stream, such as a pipe). Will raise an IOError if the stream is not duplexed.
f = IO.popen("/bin/sh","r+")
f.close_write
f.print "nowhere"
produces:
prog.rb:3:in `write': not opened for writing (IOError)
from prog.rb:3:in `print'
from prog.rb:3
249 250 251 252 |
# File 'lib/redisk/io.rb', line 249 def close_write @write_open = false nil end |
#closed? ⇒ Boolean
ios.closed? => true or false Returns true if ios is completely closed (for duplex streams, both reader and writer), false otherwise.
f = File.new("testfile")
f.close #=> nil
f.closed? #=> true
f = IO.popen("/bin/sh","r+")
f.close_write #=> nil
f.closed? #=> false
f.close_read #=> nil
f.closed? #=> true
266 267 268 |
# File 'lib/redisk/io.rb', line 266 def closed? !(@write_open || @read_open) end |
#dir ⇒ Object
46 47 48 |
# File 'lib/redisk/io.rb', line 46 def dir self.class.dir end |
#each(&block) ⇒ Object Also known as: each_line
ios.each(sep_string=$/) {|line| block } => ios ios.each_line(sep_string=$/) {|line| block } => ios Executes the block for every line in ios, where lines are separated by sep_string. ios must be opened for reading or an IOError will be raised.
f = File.new("testfile")
f.each {|line| puts "#{f.lineno}: #{line}" }
produces:
1: This is line one
2: This is line two
3: This is line three
4: And so on...
283 284 285 286 287 288 289 |
# File 'lib/redisk/io.rb', line 283 def each(&block) rewind length.times do yield gets end self end |
#each_byte ⇒ Object
ios.each_byte {|byte| block } => nil Calls the given block once for each byte (0..255) in ios, passing the byte as an argument. The stream must be opened for reading or an IOError will be raised.
f = File.new("testfile")
checksum = 0
f.each_byte {|x| checksum ^= x } #=> #<File:testfile>
checksum #=> 12
301 302 303 304 305 306 307 |
# File 'lib/redisk/io.rb', line 301 def each_byte rewind while !eof? yield getc end self end |
#eof ⇒ Object Also known as: eof?
ios.eof => true or false ios.eof? => true or false Returns true if ios is at end of file that means there are no more data to read. The stream must be opened for reading or an IOError will be raised.
f = File.new("testfile")
dummy = f.readlines
f.eof #=> true
If ios is a stream such as pipe or socket, IO#eof? blocks until the other end sends some data or closes it.
r, w = IO.pipe
Thread.new { sleep 1; w.close }
r.eof? #=> true after 1 second blocking
r, w = IO.pipe
Thread.new { sleep 1; w.puts "a" }
r.eof? #=> false after 1 second blocking
r, w = IO.pipe
r.eof? # blocks forever
Note that IO#eof? reads data to a input buffer. So IO#sysread doesn‘t work with IO#eof?.
333 334 335 |
# File 'lib/redisk/io.rb', line 333 def eof lineno >= length || pos >= size end |
#fcntl(integer_cmd, arg) ⇒ Object
ios.fcntl(integer_cmd, arg) => integer Provides a mechanism for issuing low-level commands to control or query file-oriented I/O streams. Arguments and results are platform dependent. If arg is a number, its value is passed directly. If it is a string, it is interpreted as a binary sequence of bytes (Array#pack might be a useful way to build this string). On Unix platforms, see fcntl(2) for details. Not implemented on all platforms.
345 346 347 |
# File 'lib/redisk/io.rb', line 345 def fcntl(integer_cmd, arg) end |
#fileno ⇒ Object Also known as: to_i
ios.fileno => fixnum ios.to_i => fixnum Returns an integer representing the numeric file descriptor for ios.
$stdin.fileno #=> 0
$stdout.fileno #=> 1
355 356 |
# File 'lib/redisk/io.rb', line 355 def fileno end |
#flush ⇒ Object
ios.flush => ios Flushes any buffered data within ios to the underlying operating system (note that this is Ruby internal buffering only; the OS may buffer the data as well).
$stdout.print "no newline"
$stdout.flush
produces:
no newline
369 370 371 372 373 374 375 376 377 |
# File 'lib/redisk/io.rb', line 369 def flush if @write_buffer && @write_buffer != '' redis.rpush list_key, @write_buffer @size += @write_buffer.length stat.write_attribute(:size, @size) stat.write_attribute(:mtime, Time.now) end @write_buffer = nil end |
#from_file(file) ⇒ Object
Reads the contents of file into the IO. If file is not a File its taken as a path and passed to File.open Returns the IO
392 393 394 395 396 397 398 399 |
# File 'lib/redisk/io.rb', line 392 def from_file(file) file = File.open(file, 'r') if !file.is_a?(File) file.each_line do |l| write l end file.close self end |
#fsync ⇒ Object
ios.fsync => 0 or nil Immediately writes all buffered data in ios to disk. Returns nil if the underlying operating system does not support fsync(2). Note that fsync differs from using IO#sync=. The latter ensures that data is flushed from Ruby‘s buffers, but doesn‘t not guarantee that the underlying operating system actually writes it to disk.
385 386 387 |
# File 'lib/redisk/io.rb', line 385 def fsync false end |
#getc ⇒ Object
ios.getc => fixnum or nil Gets the next 8-bit byte (0..255) from ios. Returns nil if called at end of file.
f = File.new("testfile")
f.getc #=> 84
f.getc #=> 104
420 421 422 |
# File 'lib/redisk/io.rb', line 420 def getc read(1).to_s.ord end |
#gets ⇒ Object
ios.gets(sep_string=$/) => string or nil Reads the next “line’’ from the I/O stream; lines are separated by sep_string. A separator of nil reads the entire contents, and a zero-length separator reads the input a paragraph at a time (two successive newlines in the input separate paragraphs). The stream must be opened for reading or an IOError will be raised. The line read in will be returned and also assigned to $_. Returns nil if called at end of file.
File.new("testfile").gets #=> "This is line one\n"
$_ #=> "This is line one\n"
435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/redisk/io.rb', line 435 def gets check_stream_open!(:read) flush return nil if eof? val = redis.lrange(list_key, lineno, lineno + 1) if val = val.first self.lineno += 1 $_ = @_ = val @pos += val.length val end end |
#inspect ⇒ Object Also known as: to_s
Return a string describing this IO object.
449 450 451 |
# File 'lib/redisk/io.rb', line 449 def inspect "#<Redisk::IO (#{name})>" end |
#ioctl(integer_cmd, arg) ⇒ Object
ios.ioctl(integer_cmd, arg) => integer Provides a mechanism for issuing low-level commands to control or query I/O devices. Arguments and results are platform dependent. If arg is a number, its value is passed directly. If it is a string, it is interpreted as a binary sequence of bytes. On Unix platforms, see ioctl(2) for details. Not implemented on all platforms.
462 463 |
# File 'lib/redisk/io.rb', line 462 def ioctl(integer_cmd, arg) end |
#isatty ⇒ Object
ios.isatty => true or false ios.tty? => true or false Returns true if ios is associated with a terminal device (tty), false otherwise.
469 470 471 |
# File 'lib/redisk/io.rb', line 469 def isatty false end |
#length ⇒ Object Also known as: lines
the number of lines in the current list/file
474 475 476 |
# File 'lib/redisk/io.rb', line 474 def length redis.llen list_key end |
#lineno ⇒ Object
ios.lineno => integer Returns the current line number in ios. The stream must be opened for reading. lineno counts the number of times gets is called, rather than the number of newlines encountered. The two values will differ if gets is called with a separator other than newline. See also the $. variable.
f = File.new("testfile")
f.lineno #=> 0
f.gets #=> "This is line one\n"
f.lineno #=> 1
f.gets #=> "This is line two\n"
f.lineno #=> 2
500 501 502 |
# File 'lib/redisk/io.rb', line 500 def lineno @lineno end |
#lineno=(num) ⇒ Object
ios.lineno = integer => integer Manually sets the current line number to the given value. $. is updated only on the next read.
f = File.new("testfile")
f.gets #=> "This is line one\n"
$. #=> 1
f.lineno = 1000
f.lineno #=> 1000
$. # lineno of last read #=> 1
f.gets #=> "This is line two\n"
$. # lineno of last read #=> 1001
516 517 518 |
# File 'lib/redisk/io.rb', line 516 def lineno=(num) @lineno = num.to_i end |
#list_key ⇒ Object
34 35 36 |
# File 'lib/redisk/io.rb', line 34 def list_key self.class.list_key(name) end |
#open?(stream = nil) ⇒ Boolean
520 521 522 523 524 525 526 |
# File 'lib/redisk/io.rb', line 520 def open?(stream = nil) if stream instance_variable_get("@#{stream}_open") else @write_open && @read_open end end |
#pid ⇒ Object
ios.pid => fixnum Returns the process ID of a child process associated with ios. This will be set by IO::popen.
pipe = IO.popen("-")
if pipe
$stderr.puts "In parent, child pid is #{pipe.pid}"
else
$stderr.puts "In child, pid is #{$$}"
end
produces:
In child, pid is 26209
In parent, child pid is 26209
542 543 544 |
# File 'lib/redisk/io.rb', line 542 def pid Process.pid end |
#pos ⇒ Object Also known as: tell
ios.pos => integer ios.tell => integer Returns the current offset (in bytes) of ios.
f = File.new("testfile")
f.pos #=> 0
f.gets #=> "This is line one\n"
f.pos #=> 17
554 555 556 |
# File 'lib/redisk/io.rb', line 554 def pos @pos end |
#pos=(num) ⇒ Object
ios.pos = integer => integer Seeks to the given position (in bytes) in ios.
f = File.new("testfile")
f.pos = 17
f.gets #=> "This is line two\n"
565 566 567 568 569 570 571 572 573 |
# File 'lib/redisk/io.rb', line 565 def pos=(num) current_pos = @pos if num < current_pos @pos = 0 else num -= current_pos end read(num) end |
#print(*args) ⇒ Object
ios.print() => nil ios.print(obj, …) => nil Writes the given object(s) to ios. The stream must be opened for writing. If the output record separator ($) is not nil, it will be appended to the output. If no arguments are given, prints $_. Objects that aren‘t strings will be converted by calling their to_s method. With no argument, prints the contents of the variable $_. Returns nil.
$stdout.print("This is ", 100, " percent.\n")
produces:
This is 100 percent.
587 588 589 590 591 592 |
# File 'lib/redisk/io.rb', line 587 def print(*args) args.empty? ? write(@_) : write(args.collect {|a| a.to_s }.join) nil end |
#printf(format_string, *args) ⇒ Object
ios.printf(format_string [, obj, …] ) => nil Formats and writes to ios, converting parameters under control of the format string. See Kernel#sprintf for details.
597 598 599 600 |
# File 'lib/redisk/io.rb', line 597 def printf(format_string, *args) write sprintf(format_string, *args) nil end |
#putc(obj) ⇒ Object
ios.putc(obj) => obj If obj is Numeric, write the character whose code is obj, otherwise write the first character of the string representation of obj to ios.
$stdout.putc "A"
$stdout.putc 65
produces:
AA
611 612 613 |
# File 'lib/redisk/io.rb', line 611 def putc(obj) self << obj.is_a?(Fixnum) ? obj : obj.to_s[0] end |
#puts(*args) ⇒ Object
ios.puts(obj, …) => nil Writes the given objects to ios as with IO#print. Writes a record separator (typically a newline) after any that do not already end with a newline sequence. If called with an array argument, writes each element on a new line. If called without arguments, outputs a single record separator.
$stdout.puts("this", "is", "a", "test")
produces:
this
is
a
test
629 630 631 632 633 634 635 636 637 |
# File 'lib/redisk/io.rb', line 629 def puts(*args) args.empty? ? write("\n") : args.each {|a| a += "\n" if a !~ /\n$/ write(a) } nil end |
#read(length = nil, buffer = nil) ⇒ Object
ios.read([length [, buffer]]) => string, buffer, or nil Reads at most length bytes from the I/O stream, or to the end of file if length is omitted or is nil. length must be a non-negative integer or nil. If the optional buffer argument is present, it must reference a String, which will receive the data.
At end of file, it returns nil or “” depend on length. ios.read() and ios.read(nil) returns “”. ios.read(positive-integer) returns nil.
f = File.new("testfile")
f.read(16) #=> "This is line one"
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
# File 'lib/redisk/io.rb', line 650 def read(length = nil, buffer = nil) check_stream_open!(:read) if eof length ? nil : "" else if length @read_buffer ||= "" fetched = false while @read_buffer.length < length && !eof? @read_buffer << gets.to_s fetched = true end result = @read_buffer[0...length] @read_buffer = @read_buffer[length..-1] || "" if fetched @pos -= @read_buffer.length else @pos += result.length end else result = readlines.join end buffer ? buffer.replace(buffer + result) : result end end |
#read_nonblock ⇒ Object
ios.read_nonblock(maxlen) => string ios.read_nonblock(maxlen, outbuf) => outbuf Reads at most maxlen bytes from ios using read(2) system call after O_NONBLOCK is set for the underlying file descriptor.
If the optional outbuf argument is present, it must reference a String, which will receive the data.
read_nonblock just calls read(2). It causes all errors read(2) causes: EAGAIN, EINTR, etc. The caller should care such errors.
read_nonblock causes EOFError on EOF.
If the read buffer is not empty, read_nonblock reads from the buffer like readpartial. In this case, read(2) is not called.
692 693 694 |
# File 'lib/redisk/io.rb', line 692 def read_nonblock end |
#readbytes(n) ⇒ Object
readbytes(n) Reads exactly n bytes.
If the data read is nil an EOFError is raised.
If the data read is too short a TruncatedDataError is raised and the read data is obtainable via its data method.
705 706 707 708 709 710 711 712 713 714 |
# File 'lib/redisk/io.rb', line 705 def readbytes(n) result = read(n) if result && result.length < n raise TruncatedDataError, result elsif result.nil? raise EOFError, "You have reached the end of the IO stream" else result end end |
#readchar ⇒ Object
ios.readchar => fixnum Reads a character as with IO#getc, but raises an EOFError on end of file.
719 720 721 |
# File 'lib/redisk/io.rb', line 719 def readchar end |
#readline ⇒ Object
ios.readline(sep_string=$/) => string Reads a line as with IO#gets, but raises an EOFError on end of file.
725 726 727 728 729 730 731 |
# File 'lib/redisk/io.rb', line 725 def readline if eof? raise EOFError, "At the end of the IO #{inspect}" else gets end end |
#readlines ⇒ Object
ios.readlines(sep_string=$/) => array Reads all of the lines in ios, and returns them in anArray. Lines are separated by the optional sep_string. If sep_string is nil, the rest of the stream is returned as a single record. The stream must be opened for reading or an IOError will be raised.
f = File.new("testfile")
f.readlines[0] #=> "This is line one\n"
741 742 743 744 |
# File 'lib/redisk/io.rb', line 741 def readlines check_stream_open!(:read) self.class.readlines(name) end |
#readpartial ⇒ Object
ios.readpartial(maxlen) => string ios.readpartial(maxlen, outbuf) => outbuf Reads at most maxlen bytes from the I/O stream. It blocks only if ios has no data immediately available. It doesn‘t block if some data available. If the optional outbuf argument is present, it must reference a String, which will receive the data. It raises EOFError on end of file.
readpartial is designed for streams such as pipe, socket, tty, etc. It blocks only when no data immediately available. This means that it blocks only when following all conditions hold.
the buffer in the IO object is empty. the content of the stream is empty. the stream is not reached to EOF. When readpartial blocks, it waits data or EOF on the stream. If some data is reached, readpartial returns with the data. If EOF is reached, readpartial raises EOFError.
When readpartial doesn‘t blocks, it returns or raises immediately. If the buffer is not empty, it returns the data in the buffer. Otherwise if the stream has some content, it returns the data in the stream. Otherwise if the stream is reached to EOF, it raises EOFError.
r, w = IO.pipe # buffer pipe content
w << "abc" # "" "abc".
r.readpartial(4096) #=> "abc" "" ""
r.readpartial(4096) # blocks because buffer and pipe is empty.
r, w = IO.pipe # buffer pipe content
w << "abc" # "" "abc"
w.close # "" "abc" EOF
r.readpartial(4096) #=> "abc" "" EOF
r.readpartial(4096) # raises EOFError
r, w = IO.pipe # buffer pipe content
w << "abc\ndef\n" # "" "abc\ndef\n"
r.gets #=> "abc\n" "def\n" ""
w << "ghi\n" # "def\n" "ghi\n"
r.readpartial(4096) #=> "def\n" "" "ghi\n"
r.readpartial(4096) #=> "ghi\n" "" ""
Note that readpartial behaves similar to sysread. The differences are:
If the buffer is not empty, read from the buffer instead of “sysread for buffered IO (IOError)”. It doesn‘t cause Errno::EAGAIN and Errno::EINTR. When readpartial meets EAGAIN and EINTR by read system call, readpartial retry the system call. The later means that readpartial is nonblocking-flag insensitive. It blocks on the situation IO#sysread causes Errno::EAGAIN as if the fd is blocking mode.
797 798 799 |
# File 'lib/redisk/io.rb', line 797 def readpartial end |
#reopen ⇒ Object
ios.reopen(other_IO) => ios ios.reopen(path, mode_str) => ios Reassociates ios with the I/O stream given in other_IO or to a new stream opened on path. This may dynamically change the actual class of this stream.
f1 = File.new("testfile")
f2 = File.new("testfile")
f2.readlines[0] #=> "This is line one\n"
f2.reopen(f1) #=> #<File:testfile>
f2.readlines[0] #=> "This is line one\n"
812 813 814 |
# File 'lib/redisk/io.rb', line 812 def reopen() end |
#rewind ⇒ Object
ios.rewind => 0 Positions ios to the beginning of input, resetting lineno to zero.
f = File.new("testfile")
f.readline #=> "This is line one\n"
f.rewind #=> 0
f.lineno #=> 0
f.readline #=> "This is line one\n"
824 825 826 827 |
# File 'lib/redisk/io.rb', line 824 def rewind self.lineno = 0 self.pos = 0 end |
#scanf ⇒ Object
scanf(str,&b) The trick here is doing a match where you grab one line of input at a time. The linebreak may or may not occur at the boundary where the string matches a format specifier. And if it does, some rule about whitespace may or may not be in effect…
That‘s why this is much more elaborate than the string version.
For each line: Match succeeds (non-emptily) and the last attempted spec/string sub-match succeeded:
could the last spec keep matching?
yes: save interim results and continue (next line)
The last attempted spec/string did not match:
are we on the next-to-last spec in the string?
yes:
is fmt_string.string_left all spaces?
yes: does current spec care about input space?
yes: fatal failure
no: save interim results and continue
no: continue [this state could be analyzed further]
852 853 854 |
# File 'lib/redisk/io.rb', line 852 def scanf end |
#seek(offset, whence = SEEK_SET) ⇒ Object
ios.seek(amount, whence=SEEK_SET) → 0 Seeks to a given offset anInteger in the stream according to the value of whence:
IO::SEEK_CUR | Seeks to _amount_ plus current position
--------------+----------------------------------------------------
IO::SEEK_END | Seeks to _amount_ plus end of stream (you probably
| want a negative value for _amount_)
--------------+----------------------------------------------------
IO::SEEK_SET | Seeks to the absolute location given by _amount_
Example:
f = File.new("testfile")
f.seek(-13, IO::SEEK_END) #=> 0
f.readline #=> "And so on...\n"
875 876 877 878 879 880 881 882 883 884 885 |
# File 'lib/redisk/io.rb', line 875 def seek(offset, whence = SEEK_SET) case whence when SEEK_SET self.pos = offset when SEEK_END self.pos = size + offset when SEEK_CUR self.pos += offset end 0 end |
#seek_lines(offset, whence = SEEK_SET) ⇒ Object
works just like seek, but seeks by lineno instead of pos
888 889 890 891 892 893 894 895 896 897 898 |
# File 'lib/redisk/io.rb', line 888 def seek_lines(offset, whence = SEEK_SET) case whence when SEEK_SET self.lineno = offset when SEEK_END self.lineno = length + offset when SEEK_CUR self.lineno += offset end 0 end |
#size ⇒ Object
the estimated size in bytes of the current file
480 481 482 |
# File 'lib/redisk/io.rb', line 480 def size @size end |
#stat ⇒ Object
ios.stat => stat Returns status information for ios as an object of type File::Stat.
f = File.new("testfile")
s = f.stat
"%o" % s.mode #=> "100644"
s.blksize #=> 4096
s.atime #=> Wed Apr 09 08:53:54 CDT 2003
908 909 910 |
# File 'lib/redisk/io.rb', line 908 def stat @stat ||= Redisk::Stat.new(name) end |
#sync ⇒ Object
ios.sync => true or false Returns the current “sync mode’’ of ios. When sync mode is true, all output is immediately flushed to the underlying operating system and is not buffered by Ruby internally. See also IO#fsync.
f = File.new("testfile")
f.sync #=> false
919 920 921 |
# File 'lib/redisk/io.rb', line 919 def sync @sync end |
#sync=(setting) ⇒ Object
ios.sync = boolean => boolean Sets the “sync mode’’ to true or false. When sync mode is true, all output is immediately flushed to the underlying operating system and is not buffered internally. Returns the new state. See also IO#fsync.
f = File.new("testfile")
f.sync = true
(produces no output)
931 932 933 |
# File 'lib/redisk/io.rb', line 931 def sync=(setting) @sync = !!setting end |
#sysread(num) ⇒ Object
ios.sysread(integer ) => string Reads integer bytes from ios using a low-level read and returns them as a string. Do not mix with other methods that read from ios or you may get unpredictable results. Raises SystemCallError on error and EOFError at end of file.
f = File.new("testfile")
f.sysread(16) #=> "This is line one"
943 944 945 |
# File 'lib/redisk/io.rb', line 943 def sysread(num) end |
#sysseek(offset, whence = SEEK_SET) ⇒ Object
955 956 |
# File 'lib/redisk/io.rb', line 955 def sysseek(offset, whence = SEEK_SET) end |
#syswrite(string) ⇒ Object
ios.syswrite(string) => integer Writes the given string to ios using a low-level write. Returns the number of bytes written. Do not mix with other methods that write to ios or you may get unpredictable results. Raises SystemCallError on error.
f = File.new("out", "w")
f.syswrite("ABCDEF") #=> 6
965 966 967 |
# File 'lib/redisk/io.rb', line 965 def syswrite(string) end |
#to_file(file) ⇒ Object
Writes the contents of IO into file. If file is not a File its taken as a path and passed to File.open Returns the IO
404 405 406 407 408 409 410 411 |
# File 'lib/redisk/io.rb', line 404 def to_file(file) file = File.open(file, 'w') if !file.is_a?(File) each_line do |l| file.write l end file.close self end |
#true_size ⇒ Object
484 485 486 |
# File 'lib/redisk/io.rb', line 484 def true_size readlines.join.length end |
#truncate(size = 0) ⇒ Object
truncate the IO to size, taking only the last [size] lines
970 971 972 973 974 975 976 977 978 979 |
# File 'lib/redisk/io.rb', line 970 def truncate(size = 0) size = size.to_i if size == 0 redis.del list_key else redis.ltrim list_key, -size, -1 end stat.write_attribute(:size, @size = true_size) length end |
#ungetc(integer) ⇒ Object
ios.ungetc(integer) => nil Pushes back one character (passed as a parameter) onto ios, such that a subsequent buffered read will return it. Only one character may be pushed back before a subsequent read operation (that is, you will be able to read only the last of several characters that have been pushed back). Has no effect with unbuffered reads (such as IO#sysread).
f = File.new("testfile") #=> #<File:testfile>
c = f.getc #=> 84
f.ungetc(c) #=> nil
f.getc #=> 84
992 993 994 995 996 997 |
# File 'lib/redisk/io.rb', line 992 def ungetc(integer) check_stream_open!(:write) char = ("" << integer) self << char nil end |
#unlink ⇒ Object Also known as: delete
Removes all references to the IO and closes it for reading and writing
1000 1001 1002 1003 |
# File 'lib/redisk/io.rb', line 1000 def unlink close self.class.unlink(name) end |
#write(string) ⇒ Object
ios.write(string) => integer Writes the given string to ios. The stream must be opened for writing. If the argument is not a string, it will be converted to a string using to_s. Returns the number of bytes written.
count = $stdout.write( "This is a test\n" )
puts "That was #{count} bytes of data"
produces:
This is a test
That was 15 bytes of data
1017 1018 1019 1020 1021 1022 1023 |
# File 'lib/redisk/io.rb', line 1017 def write(string) check_stream_open!(:write) string = string.to_s self << string flush string.length end |
#write_nonblock(string) ⇒ Object
ios.write_nonblock(string) => integer Writes the given string to ios using write(2) system call after O_NONBLOCK is set for the underlying file descriptor.
write_nonblock just calls write(2). It causes all errors write(2) causes: EAGAIN, EINTR, etc. The result may also be smaller than string.length (partial write). The caller should care such errors and partial write.
1034 1035 |
# File 'lib/redisk/io.rb', line 1034 def write_nonblock(string) end |