ruby IO及其子类File和Dir

IO(input/output) 即输入输出对象。
在程序启动时就会分配三个IO对象,分别为标出输入、标准输出和错误输出。

$stdin
STDIN
$stdout
STDOUT
$stderr
STDERR

检查标准输入是否为屏幕

$stdin.tty?

File


IO的子类,主要用于文件的输出和输入。
io = File.open(file[, mode[, perm]][, opt])
io = open(file[, mode[, perm]][, opt])
file.close
通过 File.open 方法或 open 方法打开文件并获取新的 IO 对象。

mode

模式(mode)会指定以何种目的打开文件(表 17.1)。缺省模式为只读模式("r")。在 Windows 环境下,在各模式后加上 b,通过 "rb"、"rb+" 等形式即可表示二进制模式(后述)。Windows 以 外的平台会忽略 b 模式,不过为了便于辨别目标文件的类型,建议操作二进制文件时还是使用 b 模式。像 "rt" 这样,在各模式末尾加上 t,会将读写时的换行符统一为 \n。

模式 意义
"r" 用只读模式打开文件
"r+" 用读写模式打开文件
"w" 用只写模式打开文件。文件不存在则创建新的文件;文件已存在则清空文件,即将文件大小设置为 0
"w+" 读写模式,其余同 "w"
"a" 用追加模式打开文件。文件不存在则创建新的文件
"a+" 用读取 / 追加模式打开文件。文件不存在则创建新的文件

File.read(file[, length [, offset]])): 不创建file对象直接读取file里的数据.
File.binread(file[, length[, offset]]):已二进制的方式读取文件。
File.write(file[, data[, offset]]):不创建文件直接向file写入数据。
File.binwrite(file[, data[, offset]]):以二进制模式打开写入file。
File.expand_path("ruby", "/usr/bin"):join路径

Dir

Dir 修改当前工作目录
当前工作目录

puts Dir.pwd
#chdir
Dir.chdir("/var/spool/mail")
puts Dir.pwd
Dir.chdir("/tmp") do
  puts Dir.pwd
  Dir.chdir("/usr") do
    puts Dir.pwd
  end
  puts Dir.pwd
end
puts Dir.pwd

require
/Users/willyang/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/rubygems/core_ext

io.gets(rs)
io.each(rs)
io.each_line(rs)
io.readlines(rs)

while line = io.gets
  line.chomp!
end
p io.eof?

io.each_line do |line|
  line.chomp!
end

另外,用 readlines 方法可以一次性地读取所有数据,并返回将每行数据作为元素封装的 数组。

ary = io.readlines
ary.each_line do |line|
  line.chomp!
end

io.lineno: 获取行数

$stdin.each_line do |line|
     printf("%3d %s", $stdin.lineno, line)
end

io.each_char: 逐个字符读取
io.each_byte:逐个字节读取
io.getc:只读取一个字符
io.ungetc(ch): 将参数 ch 指定的字符退回到 io 的输入缓冲区中
io.getbyte: 只读取一个字节
io.ungetbyte(byte): 将一个字节退回到缓冲区
io.read(size):读取参数 size 中指定的大小的数据。不指定大小时,则一次性读取全部数据并返回.

io.puts(str0, str1, ...):在字符串末尾添加换行符后输出
io.putc(ch):输出参数 ch 指定的字符编码所对应的字符,参数为字符串时输出首字符。
io.print(str0, str1, ...):输出参数指定的字符串
io.printf(fmt, arg0, arg1, ...):按照指定的格式输出字符串
io.write(str): 输出参数 s t r 指定的字符串
io<<str:输出参数 str 指定的字符串<< 会返回接收者本身,因此可以像下面这样写

io << "foo" << "bar" << "baz"

文件指针

io.pos/io.pos=(position):通过 pos 方法可以获得文件指针现在的位置
io.seek(offset, whence):移动文件指针的方法
io.rewind:将文件指针返回到文件的开头
io.truncate(size):按照参数 size 指定的大小截断文件

二进制模式与文本模式

io.binmode:使用 binmode 方法可将其变更为二进制模式

缓冲

即使对 IO 对象进行写入,结果也并不一定马上就会反映在控制台或者文件中。在使用 write、print 等方法操作 IO 对象时,程序内部会开辟出一定的空间来保存临时生成的数据副 本(图 17.2)。这部分空间就称为缓冲区(buffer)。缓冲区里累积一定量的数据后,就会进行输 出处理,然后清空缓冲区。
io.flush:调用这个方法后会立即输出输出缓冲区中的数据
io.sync/io.sync=(state): 指定io.sync = true后,同步输出内容到文件不需要flush

与命令进行交互

IO.popen(command, mode)
用 IO.popen 方法生成的 IO 对象的输入 / 输出,会关联启动的命令 command 的标准输入 / 输出。也就是说,IO 对象的输出会作为命令的输入,命令的输出则会作为 IO 对象的输入。
open("|command", mode):将带有管道符号的命令传给 open 方法的效果与使用 IO.popen 方法是一样的。

open-uri 库

除了控制台、文件以外,进程间通信时使用的管道、网络间通信时使用的套接字也都可以作 为 I O 对象使用。管道、套接字的使用方法超出了本书的范围,因此不详细说明,这里我们简单 地介绍一下利用 HTTP、FTP 从网络获取数据的方法。

require "open-uri"
# 通过HTTP读取数据 open("http://www.ruby-lang.org/zh_cn/") do |io|
puts io.read # 将Ruby的官方网页输出到控制台 end
# 通过FTP读取数据
filename = "ruby-2.3.0.tar.gz"
url = "ftp://www.ruby-lang.org/pub/ruby/2.3/#{filename}"
open(url) do |io|
  File.binwrite(filename, io.read) # 写入文件 
end

stringio 库

在测试程序时,虽然我们希望知道向文件或控制台输出了什么,但程序实际执行的结果却往 往很难知道。为此,可以通过向模拟 IO 对象的对象进行输出来确认执行结果。
StringIO 就是用于模拟 IO 对象的对象。通过 require 引用 stringio 库后,就可以使 用 StringIO 对象了(代码清单 17.10)。

require "stringio"
io = StringIO.new
io.puts("A")
io.puts("B")
io.puts("C")
io.rewind
p io.read  #=> "A\nB\nC\n"
IO.pipe

返回对应管道两端的io对象

read_io, wirte_io = IO.pipe
wirte_io.puts '1'
# => nil
read_io.gets
# => 1
IO.popen

返回命令执行完后的输出

f = IO.popen("uname")
f.readlines
# => ["Darwin\n"]

IO.select

输入两数组的IO对象,返回包含这些IO对象的数组的数组。如果给出了可选的超时值并且在超时秒内没有准备好IO对象,它将返回nil

rp, wp = IO.pipe
mesg = "ping "
100.times {
  rs, ws, = IO.select([rp], [wp])
  if r = rs[0]
    ret = r.read(5)
    print ret
    case ret
    when /ping/
      mesg = "pong\n"
    when /pong/
      mesg = "ping "
    end
  end
  if w = ws[0]
    w.write(mesg)
  end
}
# => 
# ping pong
# ping pong
# ping pong
# (...)
# ping
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,714评论 0 38
  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 3,523评论 0 5
  • 已跻身商界女强人行列的晴美无意间得知,小学时代曾养育过自己的丸光孤儿院因夜间失火被烧毁,心怀感恩的晴美在赶去现场救...
    琥琥阅读 509评论 5 11
  • 我刚刚又一次像个外人一样挑剔地观察自己在上课时的表现。 首先、表情不好! 尤其是紧锁的眉头!我为什么不...
    晚起画蛾眉阅读 167评论 0 4
  • 哭的时候,我有时候就会想到去翻个镜子出来,看一看,那个时候我应该是比平时照镜子认真多了。 我刚刚站...
    圭柠七阅读 393评论 0 0