IOのまとめ

  • たぶんruby2.0から IO.read、IO.foreach、IO.readlines、IO.write などが思ったように使えるようになった
  • IO.readはエンコーディングを指定しなければ、「Encoding.default_external」がセットされる
  • IO.foreach、IO.readlines などはヘルプと少し食い違ってるけど、エンコーディングなどのオプション引数を指定できる
  • IO.write はエンコーディングを指定しなかったら、文字列のエンコーディングのままで書き込まれる。
# coding: utf-8

s = "--- エンコーディングはUTF-8です ---"
puts "リテラル = #{s.encoding}"
puts s

puts "Encoding.default_external => #{Encoding.default_external}" # => Windowsだと「Windows-31J」
# エンコーディングを指定しない場合は↑これが指定される

puts %q|■=== IO.read("cp932.txt") ===|
s = IO.read("cp932.txt")
puts "cp932.txt = #{s.encoding}" # => Windows-31J
puts s

puts %q|■=== IO.read("cp932.txt", :mode => "r:cp932") ===|
s = IO.read("cp932.txt", :mode => "r:cp932")
puts "cp932.txt = #{s.encoding}" # => Windows-31J
puts s

puts %q|■=== IO.read("utf8.txt") ===|
s = IO.read("utf8.txt")
puts "utf8.txt = #{s.encoding}" # => Windows-31J
puts s # 文字化け

puts %q|■=== IO.read("utf8.txt", :mode => "r:utf-8") ===|
s = IO.read("utf8.txt", :mode => "r:utf-8")
puts "utf8.txt = #{s.encoding}" # => UTF-8
puts s

puts %q|■=== IO.foreach("cp932.txt") ===|
i = 1
IO.foreach("cp932.txt"){|line|
  print "#{i}行目:"
  puts line
}

puts %q|■=== IO.foreach("utf8.txt") ===|
i = 1
IO.foreach("utf8.txt"){|line|
  print "#{i}行目:"
  puts line # 文字化け
}

# ヘルプには opts 引数について書かれていないが、やってみたらできた
puts %q|■=== IO.foreach("utf8.txt", :mode => "r:utf-8") ===|
i = 1
IO.foreach("utf8.txt", :mode => "r:utf-8"){|line|
  print "#{i}行目:"
  puts line
}

# これもヘルプには readlines(path, opts={}) というメソッドは無いけど、やってみたらできた
puts %q|■=== IO.readlines("utf8.txt", :mode => "r:utf-8") ===|
s = IO.readlines("utf8.txt", :mode => "r:utf-8")
puts s.join(",")
# ↑行末に \n が付加されているので注意

puts %q|■=== IO.write ===|
s = "ほげほげ\nふがふが"
IO.write("io-write-no-enc.txt", s) # => utf-8
IO.write("io-write-enc-utf8.txt", s, :mode => "w:utf-8") # => utf-8
IO.write("io-write-enc-cp932.txt", s, :mode => "w:cp932") # => cp932