Ruby2.0.0文档翻译:IO
IO 类,是Ruby 中所有输入和输出的基础。单个的输入输出流可能是双工的( duplexed )(也就是说,双向的),因此,可能会用上多个原生操作系统流。
本小节中狠多示例都是使用了 File 类,它是 IO 的 唯一一个标准子类。这两个类是紧密关联的。与 File 类似的是,Socket库也对 IO 进行了子类化(例如TCPSocket或UDPSocket)。
Kernel#open 方法可用来创建一个 IO (或 File )对象,它接收以下类型的参数:
•.普通的字符串,代表的是符合底层操作系统条件的文件名。
•. 以 "|" 开头的字符串,代表一个子进程。这个字符串中 "|" 之后的余下部分,会被执行,以启动一个进程,并且将适当的输入输出通道连接到它。
•. 字符串 "|-" ,会创建另一个Ruby实例,并且作为子进程来使用。
打开 IO 时,可使用不同的文件模式(只读、只写)和不同的字符编码,以满足实际需求。参考 ::new 以了解这些选项。参考 Kernel#open 以了解上面所说过的各种命令格式的详情。
::popen 、Open3库或Process#spawn,也都可以用来通过一个 IO 与子进程进行通信。
在可能的情况下,Ruby会将路径名根据不同的操作系统风格进行转换。
我们此处的示例中,会使用Unix风格的向右/;可使用File::ALT_SEPARATOR来获取到与平台相关的分隔符。
全局常量 ARGF (也可通过$<访问)提供了一个IO风格的流,可用来访问所有通过命令行指定的文件(如果未指定文件,则会是STDIN)。 ARGF#path ,以及它的别名方法 ARGF#filename ,可用来访问到当前正在读取的文件的名字。
io/console扩展,可用来与终端进行交互。终端,可通过IO.console或标准的输入/输出/错误(input/output/error) IO 对象来访问。
引入(Requiring)io/console之后,会导致加入以下方法:
•.IO::console
•.IO#raw
•.IO#raw!
•.IO#cooked
•.IO#cooked!
•.IO#getch
•.IO#echo=
•.IO#echo?
•.IO#noecho
•.IO#winsize
•.IO#winsize=
•.IO#iflush
•.IO#ioflush
•.IO#oflush
示例:
require 'io/console'
rows, columns = $stdin.winsize
puts "Your screen is #{columns} wide and #{rows} tall"
binread(name, [length [, offset]] ) → string
打开文件,根据需要跳到指定偏移 offset ,然后返回长度为 length ( 默认值是文件中剩余部分的长度 ) 个字节的数据。 binread 会确保,在返回数据之前,文件已被关闭。打开方式是“rb:ASCII-8BIT”。
IO.binread ( "testfile" ) #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
IO.binread ( "testfile", 20 ) #=> "This is line one\nThi"
IO.binread ( "testfile", 20, 10 ) #=> "ne one\nThis is line "
read(name, [length [, offset]] ) → string
read(name, [length [, offset]], open_args) → string
打开文件,根据需要跳到指定偏移 offset ,然后返回长度为 length ( 默认值是文件中剩余部分的长度 ) 个字节的数据。 read 会确保,在返回数据之前,文件已被关闭。
如果最后一个参数是一个散列(hash),那么,它将被用来指定内部的open()方法的参数。其键名如下所示。open_args:与其它参数是互斥的。
encoding
string或encoding
指定要读取的字符串的字符编码。如果指定了长度,则 encoding 会被忽略。
mode
string
指定在open()中使用的打开模式(mode)参数。它应当以“r”开头,否则会产生错误。
open_args
由string组成的array
以数组的形式为open()指定参数。
示例:
IO.read ( "testfile" ) #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
IO.read ( "testfile", 20 ) #=> "This is line one\nThi"
IO.read ( "testfile", 20, 10 ) #=> "ne one\nThis is line "
如果 ios 是关联到了一个终端设备(tty),则返回真( true ),否则返回假( false )。
File.new ( "testfile" ).isatty #=> false
File.new ( "/dev/tty" ).isatty #=> true
read([length [, outbuf]]) → string, outbuf, or nil
从这个输入输出流中读取 length 个字节。
length 必须是非负整数或者是 nil 。
如果 length 是正整数,则,会尝试在不进行字符集转换的情况下(二进制模式)读取 length 个字节。它会返回 nil 或者一个字符串,该字符串的长度为1 到 length 个字节。返回 nil 则表示它在一开始就遇到文件结束(EOF)了。而返回1到 length -1个字节的字符串呢,则表示,它在读取过程中遇到了文件结束。返回 length 个字节的字符串,则表示,在读取过程中未遇到文件结束。返回的字符串一定是ASCII-8BIT编码。
如果 length 被省略,或者其就是 nil ,那么,它会一直读取直到文件结束,并且会进行字符编码的转换。即使是一开始就遇到了文件结束,它也会返回一个字符串。
如果 length 为零,则它会返回 "" 。
outbuf 参数是可选的,如果提供了这个参数,那么, 它就必须引用某个 String ,而那个字符串会接收到最终数据。 在该方法调用完毕之后, outbuf 只会包含着最终接收到的数据,即使最初它并不为空也是如此。
遇到文件结束 的话,它会返回 nil 或 "" ,具体取决于参数 length 。 ios .read() 和 ios .read(nil) 会返回 "" 。 ios .read( positive-integer ) 会返回 nil 。
f = File.new ( "testfile" )
f.read ( 16 ) #=> "This is line one"
# 读取整个文件
open ( "file" ) {|f|
data = f.read # 这会返回一个字符串,即使文件为空也是如此。
...
}
# 对固定长度的记录进行遍历。
open ( "fixed-record-file" ) {|f|
while record = f.read ( 256 )
...
end
}
# 对可变长度的记录进行遍历。
# 记录前面有一个32位的长度字段。
open ( "variable-record-file" ) {|f|
while len = f.read ( 4 )
len = len.unpack ( "N" )[ 0 ] # 32位的长度字段
record = f.read (len) # 这会返回一个字符串,即使len为0也是如此。
end
}
注意 ,这个方法的行为与C 语言中的fread()函数类似。 这意味着,它会重复调用read(2)这个系统函数, 以读取指定长度的数据 (或者直到遇到文件结束 为止 ) 。 它明确 地具有这个行为,即使 ios 处于 非阻塞模式也是如此。 ( 这个方法,对于非阻塞标志位,是忽略的。 ) 如果 妳预期产生类似于单次 read(2)系统调用 的行为,那么,请考虑使用 readpartial 、 #read_nonblock 和 sysread 。
乌克兰持枪少女
放屁虫
柳岩
未知美人
HxLauncher: Launch Android applications by voice commands