IO类实现了基本的输出输入功能。
ruby 1.8 特性: File::Constants已经脱离了File。
IO.new(fd[, mode])IO.for_fd(fd[, mode]) ((<ruby 1.7 特性>))IO.open(fd[, mode]) ((<ruby 1.7 特性>))IO.open(fd[, mode]) {|io| ... } ((<ruby 1.7 特性>))生成并返回一个全新的IO对象,它对应于已打开的文件描述符fd。若生成IO对象失败的话,将引发Errno::EXXX异常。
可以采用与File.open相同的形式来为mode指定一个IO模式(但只能是字符串形式)。详情请参考内部函数open。 mode的默认值为 "r"。
ruby 1.7 特性: IO.for_fd与IO.new相同。IO.open稍有不同,因为它可以带块(块运行结束时fd会被关闭)。
带块的IO.open返回块的结果。其他的返回生成的IO对象。
ruby 1.8 特性: 指定mode的方法与open,File.open完全相同。(也就是说,在1.8以后的版本中,可以使用File::RDONLY等常数(数值)来指定mode)
IO.foreach(path[, rs]) {|line| ... }对path所指文件的各行内容进行迭代操作(与open一样,若path以"|"开头的话则读取命令输出)。其运作情形如下。
port = open(path)
begin
port.each_line {|line|
...
}
ensure
port.close
end
若成功打开path就返回nil。若失败则引发Errno::EXXX异常。
使用rs所指字符串进行行的切分,rs的默认值取自内部变量$/。
若将rs指定为nil,则意味着忽略行的切分。若指定为空字符串""的话,将把连续的换行当作行的切分符(段落模式)。
IO.pipe执行pipe(2)后返回一个数组,该数组包括2个互联的IO对象。若没有成功生成IO对象的话,将引发Errno::EXXX异常。
返回数组中的首元素负责读取,第二个元素负责读入。
p pipe = IO.pipe # => [#<IO:0x401b90f8>, #<IO:0x401b7718>] pipe[1].puts "foo" p pipe[0].gets # => "foo\n"
IO.popen(command [, mode])IO.popen(command [, mode]) {|io| ... }将command作为子进程来运行,然后建立一条连接到该进程的输入输出的管线(pipeline)。mode指定打开IO端口的模式(欲知mode详情,请参考open)。省略时将使用默认值 "r"。
返回生成的管道(IO对象)。
p io = IO.popen("cat", "r+") # => #<IO:0x401b75c8>
io.puts "foo"
p io.gets # => "foo\n"
若带块时,将以生成的IO对象为参数来运行该块,并返回其结果。在块得到运行以后,生成的管道将会自动关闭。
p IO.popen("cat", "r+") {|io|
io.puts "foo"
io.gets
}
# => "foo\n"
当命令名为"-"时,Ruby将运行fork(2)来建立一个连接到子进程的输入输出的管线。此时,父进程将返回IO对象,子进程返回nil。若带块的话,父进程以生成的IO对象为参数来运行该块并返回其结果。(管道被关闭)子进程以nil为参数来运行该块然后终止运行。
# 不带块的例子
io = IO.popen("-", "r+")
if io.nil?
# child
s = gets
print "child output: " + s
exit
end
# parent
io.puts "foo"
p io.gets # => "child output: foo\n"
io.close
# 带块的例子
p IO.popen("-", "r+") {|io|
if io
# parent
io.puts "foo"
io.gets
else
# child
s = gets
puts "child output: " + s
end
}
# => "child output: foo\n"
若没有成功生成管道或子进程时,将引发Errno::EXXX异常。
ruby 1.9 特性: 若command为数组则不必通过shell即可运行子进程。
IO.read(path,[length,[offset]]) ((<ruby 1.7 特性>))在path所指文件中,从offset位置开始读入length字节的内容并将其返回。其运作情形如下。
port = open(path) port.pos = offset if offset begin port.read length ensure port.close end
若length为nil或被省略时,将一直读到EOF。
若IO已经到达EOF时则返回nil。
若无法打开path,或者设定offset所指位置失败,又或者无法读入文件内容时,都将引发Errno::EXXX异常。若length为负数,则会引发ArgumentError异常。
IO.readlines(path[, rs])读入path所指文件的全部内容后,以行为单位将其转化为数组并返回该数组。若IO已经到达EOF时返回空数组[]。
其运作情形如下。
port = open(path) begin port.readlines ensure port.close end
使用rs所指字符串进行行的切分,rs的默认值取自内部变量$/。
若将rs指定为nil,则意味着忽略行的切分。若指定为空字符串""的话,将把连续的换行当作行的切分符(段落模式)。
若无法打开path或者读取文件失败时,将引发Errno::EXXX异常。
IO.select(reads[, writes[, excepts[, timeout]]])执行select(2)。传递给reads/writes/excepts的是等待输入的IO(或其子类)的实例的数组。
timeout可以是整数、Float或nil(省略时的默认值)。指定为nil时,将会一直等到IO变成就绪状态。
timeout时将返回nil,除此以外将返回一个包含3个元素的数组,这3个元素分别是等待输入/输出/异常的对象的数组(指定数组的子集)。
与select相同。
IO.sysopen(path[, mode [, perm]]) ((<ruby 1.7 特性>))打开path所指文件并返回文件描述符。若无法打开文件时将引发Errno::EXXX异常。
参数mode, perm的具体情况与内部函数open相同。
如果不使用IO.for_fd等来转化为IO对象的话,就无法关闭使用该方法打开的文件。
self << object输出object。若object并非字符串时,将使用to_s方法将其变为字符串。该方法以self作为返回值,因此可以像下面这样使用一连串的<<。
STDOUT << 1 << " is a " << Fixnum << "\n"
若输出失败时将引发Errno::EXXX异常。
binmode将流变为二进制模式。该方法只在那些支持二进制模式的OS,如MSDOS中有效(除此以外将毫无反应)。若想从二进制模式恢复到普通模式时,只能重新打开。
返回self。
clonedup返回一个全新的IO对象,该对象与receiver使用同一个IO。(请参考dup(2)来了解所用的文件描述符)。clone时self暂时被flush。
对一个被冻结的IO使用clone时,同样会得到一个被冻结的IO。如果使用dup则会返回一个内容相同但未被冻结的IO。
close关闭输入输出端口。
此后,若对该端口进行输入输出的话会引发IOError异常。进行垃圾回收时,未关闭的IO端口将被关闭。Traps:将close托付给GC。
若close失败则引发Errno::EXXX异常。
若self已被管道连接到进程上时,将等待该进程的结束。
返回nil。
close_read关闭读取用的IO。主要用在管道或读写两用的IO对象上。
若self并非读取用IO,则引发IOError异常。
若close失败则引发Errno::EXXX异常。
返回nil。
close_write关闭写入用的IO。
若self并非写入用IO,则引发IOError异常。
若close失败则引发Errno::EXXX异常。
返回nil。
closed?若端口已被关闭则返回真。
each([rs]) {|line| ... }each_line([rs]) {|line| ... }每次从IO端口读入1行来进行相关处理的迭代器。IO端口必须是以读模式打开的(请参考open)。
使用rs所指字符串进行行的切分,rs的默认值取自内部变量$/。
若将rs指定为nil,则意味着忽略行的切分。若指定为空字符串""的话,将把连续的换行当作行的切分符(段落模式)。
返回self。
each_byte {|ch| ... }每次从IO端口读入1字节的内容。IO端口必须是以读模式打开的(请参考open)。
返回self。
eofeof?若流(stream)到达文件末端时返回真。
fcntl(cmd[, arg])将对IO执行系统调用fcntl。请参考fcntl(2)了解详细的功能。
若arg为整数,则把它原封不动地传递给fcntl(2)。若为true以及false,则分别传递1和0。若为字符串,则会被当作pack过的结构体(structure)来传给fcntl(2)。 若省略arg时,其默认值为0。
cmd可以使用附加库fcntl.so中Fcntl模块所提供的值。
返回fcntl(2)的返回值。若未能成功执行fcntl(2)时,将引发Errno::EXXX异常。
fsync ((<ruby 1.7 特性>))对写入用的IO执行系统调用fsync(2)。在flush之后(在OS级别上)将内存中尚未保存到硬盘上的数据写入硬盘。
成功就返回 0。失败则引发Errno::EXXX异常。若self并非写入用IO时,将引发IOError异常。
filenoto_i返回文件描述符的号码。
flush刷新IO端口的内部缓冲区。 若self并非写入用IO时,将引发IOError异常。
返回self。
getc从IO端口读入1个字符,并返回该字符对应的Fixnum。到达EOF时返回nil。
gets([rs])读入一行,若成功的话就返回读入的字符串。到达文件末尾时返回nil。其动作与IO#each相同,只不过该方法不进行迭代操作而已。
使用rs所指字符串进行行的切分,rs的默认值取自内部变量$/。
若将rs指定为nil,则意味着忽略行的切分。若指定为空字符串""的话,将把连续的换行当作行的切分符(段落模式)。
IO#gets与gets一样,将读入的字符串赋值给变量$_。
ioctl(cmd[, arg])对IO执行系统调用ioctl,并返回其结果。请参考ioctl(2)以了解详细的功能。
若arg为整数时就将其原封不动地传递给ioctl。若为字符串,则被看作pack过的结构体来传给ioctl。若省略arg或其值为nil以及false时,将传递0。若为true时将传递1。
isattytty?若输出输入端口已与tty结合时,返回真。
lineno返回当前的行号。
lineno=number设定行号。
pid若是由IO.popen所生成的IO端口时,则返回子进程的进程ID。除此以外返回nil。
postell返回文件指针的当前位置。
pos = n将文件指针移动到指定位置。与io.seek(pos, IO::SEEK_SET)相同。
print([arg[, ...]])依次将参数输出到IO端口。省略参数时将输出$_。该方法处理参数的方式与print相同(详情请参考这个方法)。
返回nil。
printf(format[, arg[, ...]])与C语言的printf一样,按照format将参数变为字符串,然后输出到self。
它与printf基本相同,只是该方法的第1个参数不能为IO,且不可省略。请参考sprintf格式化来了解处理参数的详情。
返回nil。
putc(ch)输出字符ch到self。该方法处理参数的方式与putc相同(详情请参考这个方法)。
返回ch。
puts([obj[, ...]])输出各个obj到self然后换行。该方法处理参数的方式与puts相同(详情请参考这个方法)。
返回nil。
read([length])read([length[, buf]]) ((<ruby 1.7 特性>))若给出了length时,就读取length字节的内容,然后返回该字符串。若IO已到达EOF则返回nil。
若省略length的话,将读入EOF之前的所有内容。若IO已到达EOF则返回""。
若读取数据失败则引发Errno::EXXX异常。若length为负数则引发ArgumentError异常。
ruby 1.7 特性:若将某字符串传给第二参数的话,将使用读入的数据来覆盖该字符串对象,并返回读入的数据。若该字符串的长度刚好等于length时,将不会进行内存分配。若该字符串的长度不等于length时,将暂时把字符串的长度拉长(或缩短)到length的长度(随后又将变成实际读入数据的长度)。
若在调用read方法时使用了第二参数且数据为空的话(read返回nil时),buf将变为空字符串。
buf = "x" * 20;
io = File.open("/dev/null")
p io.read(10,buf)
p buf
=> nil
""
readchar与IO#getc一样,读入1个字符后返回与该字符相对应的Fixnum。若到达EOF则引发EOFError异常。
readline([rs])与IO#gets一样,读入1行后返回读入的字符串。若到达EOF则引发EOFError异常。
使用rs所指字符串进行行的切分,rs的默认值取自内部变量$/。
若将rs指定为nil,则意味着忽略行的切分。若指定为空字符串""的话,将把连续的换行当作行的切分符(段落模式)。
readline与gets一样,将读入的字符串赋值给变量$_。
readlines([rs])读入所有数据后,以行为单位将其转化为数组,并返回该数组。若IO已到达EOF则返回空数组[]。
使用rs所指字符串进行行的切分,rs的默认值取自内部变量$/。
若将rs指定为nil,则意味着忽略行的切分。若指定为空字符串""的话,将把连续的换行当作行的切分符(段落模式)。
readpartial(maxlen[, outbuf])ruby 1.9 特性
从IO读入最多maxlen的数据,并返回读入的字符串。此时,若没有现成的数据的话,就会进入阻塞状态并一直等待数据的到来。若有现成的数据的话,哪怕只有1字节也不会进入阻塞状态。若将一个字符串传给第二参数outbuf的话,就会用读入的数据来覆盖该字符串,并返回读入的数据。若IO已到达EOF则引会发EOFError异常。
如果将阻塞所带来的影响减至最小的话,就可以让readpartial对管道、socket以及终端等的流(stream)作出恰当的反应。只有在下述条件均成立时,readpartial才会进入阻塞状态。
当上述条件均成立时,readpartial就会进入阻塞状态,直到有数据出现或者到达EOF为止。
readpartial的结果如下。
例如,下例就是在管道中使用该方法的情形。
r, w = IO.pipe # stdio buffer pipe content w << "abc" # "" "abc". r.readpartial(4096) #=> "abc" "" "" r.readpartial(4096) # 缓冲区和管道中都没有数据,因此进入阻塞状态 r, w = IO.pipe # stdio buffer pipe content w << "abc" # "" "abc" w.close # "" "abc" EOF r.readpartial(4096) #=> "abc" "" EOF r.readpartial(4096) # 发生EOFError异常 r, w = IO.pipe # stdio 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" "" ""
而且readpartial不受nonblock标识的影响。也就是说,即使设置了nonblock标识也会进入阻塞状态。
另外readpartial的运作情形与未设置nonblock标识的sysread非常相似。特别是当stdio的缓冲区为空时,就更是如出一辙了。
reopen(io)reopen(name[, mode])将自身转接到io上。类也将等同于io(请注意)。
若第一参数为字符串时,将把流转接到name所指的文件上。
第二参数的默认值为"r"。ruby 1.8 特性: 若省略第二参数时,将原封不动地继承self的模式。
返回self。
rewind将文件指针移动到头部。IO#lineno变为 0 。
seek(offset[, whence])将文件指针由whence移动到offset。whence的值是下列之一。
IO::SEEK_SET: 从文件头部开始(默认)IO::SEEK_CUR: 从当前文件指针开始IO::SEEK_END: 从文件尾部开始省略whence时,其默认值为IO::SEEK_SET。
若向着offset移动成功就返回0。若失败则引发Errno::EXXX异常。
stat生成并返回一个包含文件状态的File::Stat对象。
若未能成功读取状态则引发Errno::EXXX异常。
另外请参考File#lstat、File.stat、File.lstat。
sync以真和伪来表示当前的输出同步模式。当输出同步模式为真时,每次调用输出函数时都会刷新缓冲区。
sync=newstate设定输出同步模式。newstate为真则表示同步模式,伪则表示非同步模式。返回newstate。
sysread(length)sysread(length[, buf]) ((<ruby 1.7 特性>))使用read(2)进行输入,并返回包含输入数据的字符串。到达文件尾部时会引发EOFError异常。因其不使用stdio,所以如果和gets、getc或eof?等混合使用的话会引起意想不到的混乱。
若不能成功读取数据则引发Errno::EXXX异常。
ruby 1.7 特性:若将某字符串传给第二参数的话,将使用读入的数据来覆盖该字符串对象,并返回读入的数据。若该字符串的长度刚好等于length时,将不会进行内存分配。若该字符串的长度不等于length时,将暂时把字符串的长度拉长(或缩短)到length的长度(随后又将变成实际读入数据的长度)。
若在调用sysread方法时使用了第二参数且数据为空的话(sysread引发EOFError异常时),buf将变为空字符串。
buf = "x" * 20;
io = File.open("/dev/null")
p((io.sysread(10,buf) rescue nil))
p buf
=> nil
""
sysseek(offset[, whence]) ((<ruby 1.7 特性>))与lseek(2)相同。若将seek与sysread, syswrite混用的话会引起混乱,此时应该使用本方法。
若对已缓冲的读取IO执行该方法时,会引起IOError异常。若对已缓冲的写入IO执行该方法时,会发出警告。
File.open("/dev/zero") {|f|
buf = f.read(3)
f.sysseek(0)
}
# => -:3:in `sysseek': sysseek for buffered IO (IOError)
File.open("/dev/null", "w") {|f|
f.print "foo"
f.sysseek(0)
}
# => -:3: warning: sysseek for buffered IO
参数的使用方法与IO#seek相同。
若向着offset位置移动成功则返回移动的位置(从文件头部算起)。若移动失败则引发Errno::EXXX异常。
syswrite(string)使用write(2)来输出string。若string并非字符串,将使用to_s尝试将其变为字符串。本方法不使用stdio,因此如果与其他输出方法混用的话会引起意想不到的问题。
返回实际输出的字节数。若输出失败则引发Errno::EXXX异常。
to_io返回self。
ungetc(char)送回(unreading)char。若送回2字节以上的内容,则无法保证其准确性。
返回nil。
write(str)对IO端口输出str。若str并非字符串,将使用to_s尝试将其变为字符串。
除IO#syswrite之外的所有输出方法最后都会调用一个名为“write”的方法,因此替换本方法就可以改变输出函数的行为。
返回实际输出的字节数。若输出失败则引发Errno::EXXX异常。