Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

RubyのDir、File、IO について

742 views

Published on

RubyのDir、File、IO について

Published in: Technology
  • Be the first to comment

  • Be the first to like this

RubyのDir、File、IO について

  1. 1. Ruby の Dir、File、IO について 2018/7/10 大手町.rb #8
  2. 2. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 1自己紹介 Tomoya Kawanishi a.k.a. @cuzic エネチェンジ株式会社 チーフエンジニア 電力会社、ガス会社を切り替えるなら、エネチェンジ経由で! 一般家庭も!法人も!Ruby関西の中の人 Ruby関西の中の人 発表者として登壇くださる方、あとで声かけください。 Rubyビジネス創出展 7月20日(金)セミナーで講演予定 大阪Ruby会議01 7月21日(土) 大手町.rb の中の人 毎月 大手町.rb の開催を予定 東京駅、各線大手町駅から直結! Ruby の初級者がメインターゲット
  3. 3. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 今日のテーマ Dir、File、IO ファイルの入出力は頻出! 上記のクラス以外も含めて、いろんなテクを紹介します 2
  4. 4. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 Ruby でのファイル処理の特徴 Ruby は大クラス主義! InputStream、BufferedInputStream、FileReader みたいに似て非なるものがたくさんあったりしない 上みたいなのは IO で全部できる File クラスにもたくさんメソッドがあってベンリ! Ruby の IO はすごいっ! 低水準と高水準のメソッドが同居! 混ぜるな危険じゃない!混ぜても使えて便利。 標準添付ライブラリが超イケてる! Find、FileUtils、pathname 今回は特に私が有用だと思ったものを中心に紹介します 3
  5. 5. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 Dir.glob、 Dir.[] Dir.glob でパターンにマッチしたファイルを一発で取得できる 超便利 Dir.new とか Dir#each とかはタルくて使ってられない。 4 Dir["config.?"] #=> ["config.h"] Dir.glob("config.?") #=> ["config.h"] Dir.glob("*.[a-z][a-z]") #=> ["main.rb"] Dir.glob("*.[^r]*") #=> ["config.h"] Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"] Dir.glob("*") #=> ["config.h", "main.rb"] Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"] rbfiles = File.join("**", "*.rb") Dir.glob(rbfiles) #=> ["main.rb", "lib/song.rb", "lib/song/karaoke.rb"] Dir.glob(rbfiles, base: "lib") #=> ["song.rb", "song/karaoke.rb"] libdirs = File.join("**", "lib") Dir.glob(libdirs) #=> ["lib"] librbfiles = File.join("**", "lib", "**", "*.rb") Dir.glob(librbfiles) #=> ["lib/song.rb", "lib/song/karaoke.rb"] librbfiles = File.join("**", "lib", "*.rb") Dir.glob(librbfiles) #=> ["lib/song.rb"]
  6. 6. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 Dir.chdir いわゆる cd ディレクトリを移動できる do ~ end の中だけ該当のディレクトリ 抜けると元に戻る 5 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 /var/spool/mail /tmp /usr /tmp /var/spool/mail /var/spool/mail /tmp /usr /tmp /var/spool/mail
  7. 7. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 Find.find 標準添付ライブラリ Find もベンリ Find.find でそのディレクトリ以下のすべてのファイルを処理対象にできる スキップした方がいいディレクトリについては Find.prune で抜けられる 6 require 'find' total_size = 0 Find.find(Dir.home) do |path| if File.directory?(path) if File.basename(path).start_with?(".") Find.prune # Don't look any further into this directory. end else total_size += File.size(path) end end
  8. 8. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 File.atime, birthtime, ctime, mtime atime で最終アクセス時刻、mtime で最終変更時刻を 取得できる ctime は環境依存なので、利用には注意が必要。 Windows + NTFS などでは birthtime を使える 7 # atime 最終アクセス時刻。read しただけで更新される File.atime("testfile") #=> Wed Apr 09 08:51:48 CDT 2003 # mtime 最終変更時刻(modify time)、ファイル内容を変更した場合に更新される File.mtime("testfile") #=> Tue Apr 08 12:58:04 CDT 2003 # ctime 最終ステータス変更時刻(change time) # ファイル内容、ファイル名、パーミッションを変更した場合に更新される # ただし、Windows (NTFS) では creation time (birthtime)が返る File.ctime("testfile") #=> Wed Apr 09 08:53:13 CDT 2003 # birth time (creation time) ファイル生成時刻 (ファイルシステムと OS依存) File.birthtime("testfile") #=> Wed Apr 09 08:53:13 CDT 2003
  9. 9. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 File.basename、File.extname File.basename 私自身は非常によく使う ディレクトリ部分を取り除く。 引数を与えると、拡張子も取り除くことができる File.extname 拡張子を取得できる 8 File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb" File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby" File.basename("/home/gumby/work/ruby.rb", ".*") #=> "ruby" File.extname("test.rb") #=> ".rb" File.extname("a/b/d/test.rb") #=> ".rb" File.extname(".a/b/d/test.rb") #=> ".rb" File.extname("foo.") #=> "" File.extname("test") #=> "" File.extname(".profile") #=> "" File.extname(".profile.sh") #=> ".sh"
  10. 10. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 File.open 第2引数 mode で、読み込み用、書き込み用を指定可能 第2引数でファイルエンコーディングも指定可能 cr_newline のような String#encode のオプションも指定可能 ブロックの返り値が File.open の返り値 9 # "r" 読み込みモード、"w" 書き込みモード、 "a" 追記モード body = File.open("testfile", "r") do |f| f.read; end File.open("newfile", "w") do |f| f.write body; end File.open("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644) do |f| f.write body end File.open("unicode.txt", mode: 'w:UTF-16LE', cr_newline: true) do |f| f.puts "Hello, World!" end File.open("another_unicode.txt", mode: 'w', cr_newline: true, external_encoding: Encoding::UTF_16LE) do |f| f.puts "Hello, World!" end
  11. 11. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 File.directory?、zero?、exist?、file? ほか File.directory? : 引数がディレクトリなら true File.exist? : 引数のファイルが存在すれば true File.file? : 引数が通常のファイルなら true File.identical? : 引数を2つとり、同一のファイルなら true File.readable? : そのファイルが読み込み可能なら true File.size? : ファイルが存在し、ファイルサイズがゼロでなければ true File.symlink? : シンボリックファイルなら true File.writable? : 書き込み可能なら true File.zero? : ファイルが存在しファイルサイズがゼロならtrue 10
  12. 12. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 FileUtils FileUtils モジュールを使うとファイルの作成、コピー、削除等がカ ンタンに利用できる デバッグ出力もカンタン 11 require 'fileutils' FileUtils.cd(dir, options) FileUtils.cd(dir, options) do |dir| block end FileUtils.pwd() FileUtils.mkdir(dir, options) FileUtils.mkdir(list, options) FileUtils.mkdir_p(dir, options) FileUtils.mkdir_p(list, options) FileUtils.rmdir(dir, options) FileUtils.rmdir(list, options) FileUtils.ln(target, link, options) FileUtils.ln(targets, dir, options) FileUtils.ln_s(target, link, options) FileUtils.ln_s(targets, dir, options) FileUtils.ln_sf(target, link, options) FileUtils.cp(src, dest, options) FileUtils.cp(list, dir, options) FileUtils.cp_r(src, dest, options) FileUtils.cp_r(list, dir, options) FileUtils.mv(src, dest, options) FileUtils.mv(list, dir, options) FileUtils.rm(list, options) FileUtils.rm_r(list, options) FileUtils.rm_rf(list, options) FileUtils.install(src, dest, options) FileUtils.chmod(mode, list, options) FileUtils.chmod_R(mode, list, options) FileUtils.chown(user, group, list, options) FileUtils.chown_R(user, group, list, options) FileUtils.touch(list, options)
  13. 13. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 IO.read、IO.write IO.read : ファイルの内容を取得できる IO.write : ファイルに引数の内容を書き込む 12 IO.read("testfile") #=> "This is line one¥nThis is line two¥nThis is line three¥nAnd so on...¥n" IO.write("testfile", "0123456789") #=> 10 # File would now read: "0123456789"
  14. 14. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 IO#each_line、IO#each_char ほか IO#each_byte :1バイトごと IO#each_char :1文字ごと IO#each_codepoint : コードポイントごと IO#each_line :1行ごと 13 File.open("testfile") do |f| f.each_line do |line| puts "#{f.lineno}: #{line}" end end File.open("testfile") do |f| checksum = 0 f.each_byte do |byte| checksum ^= byte end end File.open("testfile") do |f| f.each_char do |char| print char end end File.open("testfile") do |f| f.each_codepoint.with_index do |codepoint, index| puts "#{index}: #{[codepoint].pack("U")} #{codepoint}" end end
  15. 15. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 STDIN、STDOUT、STDERR STDIN:標準入力、$stdin のデフォルト値 STDOUT:標準出力、$stdout のデフォルト値 STDERR: 標準エラー出力、$stderr のデフォルト値 $stdin: Kernel.gets や Kernel.each_line で使われる $stdout:Kernel.puts や Kernel.p で使われる $stderr:Kernel.warn で使われる 普通は f.puts などとして出力するが、 下記のようにするとより簡潔に書くこともできる。 14 File.open("tempfile") do |f| $stdout = f puts "0123456" $stdout = STDOUT end
  16. 16. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 StringIO IO のメソッド群で String を作れる さっきの $stdout と組合わせるテクもある ピンポイントで使わないとわりと混乱する 用量・用法を守ってお使いください 15 require 'stringio' io = StringIO.new io.puts "Hello World" io.string #=> "Hello World¥n" require 'stringio' io = $stdout = StringIO.new puts "Hello World" $stdout = STDOUT puts s.string #=> "Hello World¥n" require 'stringio' str = StringIO.open("") do |io| $stdout = io puts "Hello World" $stdout = STDOUT io.string end puts str #=> "Hello World¥n"
  17. 17. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 ARGF ARGV をファイル名の配列とみなして、 そのファイルの内容を簡単に ARGF でアクセスできる 事前にコマンドラインオプションを除去する必要がある 16 $ cat foo qwe 123 bar $ cat foo | ruby -e 'ARGF.each_line { |l| puts l.chop.reverse }' ruby -e 'ARGF.each_line { |l| puts l.chop.reverse }' foo ruby -lpe '$_.reverse!' foo
  18. 18. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 Pathname いろんな機能がてんこ盛りの façade クラス Pathname.glob : Pathname を yield する Dir.glob Pathname#+, / : Pathname way な文字列連結 Pathname#atime, mtime, ctime, open, basename File の同名メソッドと同一 Pathname#exist?, file?, size?, writable? ほか FileTest の同名メソッドと同一 Pathname#each_line, read IO の同名メソッドと同一 17 Rails.root #=> "." Rails.root + "bin/rails" #=> "./bin/rails"
  19. 19. 大手町.rb #8 発表資料 「Rubyの Dir、File、IOについて」 まとめ 今回は Ruby でディレクトリやファイルを扱う方法を紹 介しました。 Ruby は大クラス主義 たくさんのベンリなメソッドが少数のクラスにある 高水準なメソッドがたくさんあって使いやすい 標準添付ライブラリもベンリ! find、fileutils、pathname、stringio さくっと書きたいときに便利な ARGF 18
  20. 20. ご清聴ありがとう ございました

×