本題
今回は第17章の練習問題を解いていく。今回はIOクラスの内容だ。それでは早速解いてみる。
(1) テキストファイルからデータを読み込んで次の処理を行うスクリプトを作成してください。なお、ここでは空白や改行以外の文字の並びのことを単語と呼ぶことにします。
(a) テキストの行数を数える。
(b)テキストの単語数を数える
(c)テキストの文字数を数える
file_name = ARGV[0]
file = File.open(file_name)
# aの結果の準備
ans=0
# b,cの結果の準備
txt = []
file.each_line do |line|
ans+=1
txt.push(line.split(" "))
end
file.close
# 多次元配列を一次元配列にする(bの処理)
txt.flatten!
num1 = txt.size
# cの処理
word = txt.join
num2 = word.size
# aの結果
puts "このファイルは#{ans}行です"
# bの結果
puts "このファイルは#{num1}単語です"
# cの結果
puts "このファイルは#{num2}文字です"
a,b,cを一つのプログラムにして解いた。
コマンドラインから引数を受け取るようにした。まず、File.openでファイルを開く。aはeach_lineメソッドを使用し行数をカウントした。次に、bの単語だ。each_lineメソッドを使用したとき、txt配列に空白で区切った単語を格納させたので、その配列の要素の数をsizeメソッドで返させた。cの文字数は、flatten!メソッドを利用し、文字一つ一つを配列の要素に変換し、その配列の数を数えるようにした。自作wcコマンドのようなものだろうか。
(2) テキストファイルからデータを読み込んで次の条件に従って上書きするスクリプトを作成してください。
(a)ファイルの中の行を逆順に並べ替える
(b)ファイルの中の最初の1行だけを残して残りを削除する
(c)ファイルの中の最後の1行だけを残して残りを削除する
file_name = ARGV[0]
file = File.open(file_name,"r+")
rev_arry = []
file.each_line do |line|
rev_arry << line
end
#
rev_arry.reverse!
file.truncate(0)
file.puts rev_arry.join()
file.close
1行ずつ配列の要素として格納。それを逆さにして、頭から入れ直すようにしました。ちなみに、truncateを使いファイルの中身は空にしました。
file_name = ARGV[0]
file = File.open(file_name,"r+")
arry = []
file.each_line do |line|
arry << line
end
file.truncate(0)
file.puts arry[0]
file.close
ほぼ先ほどと同じ処理です。違うとしたら、配列の一番最初の要素だけをファイルに書き込んだことくらいです。
file_name = ARGV[0]
file = File.open(file_name,"r+")
arry = []
file.each_line do |line|
arry << line
end
file.truncate(0)
file.puts arry[-1]
file.close
b問題とほぼ同じ、こちらは配列の末尾を書き込むようにしました。
(3) Unixで使われる"tail"コマンドと似たことが出来るメソッドtailsを定義しなさい。なお、tailメソッドは2つの引数を受け取ります(tail(行数,ファイル名))
def tail(num,file)
f = open(file)
arry = []
f.each_line do |line|
arry << line
end
a = -1 * num.to_i
result = arry[a..-1]
result.each{|i| p i.chomp}
end
2_cの問題を少しイジった感じです。2_cは末尾のみだったのでそれを必要な行の要素から末尾まで返すようにしました。
(4) Fileオブジェクトへの出力が何バイトまでバッファリングされるか調べるスクリプトを作成してください。
file_name = "Test.txt"
file = File.open(file_name,"w")
10000.times do |i|
file.write("X")
size = File.size(file_name)
if size == i and i>0
break
end
p "#{i+1}回目:#{size}"
end
# 実行結果:1回目:0
# 2回目:0
# 省略
# 8192回目:8192
Test.txtというファイルに"X"という文字を増やし続けるようなプログラムにしました。すると、8192回目でTest.txtに書き込まれたことを確認することが出来ました。
最後に
今回はIOクラスについて学習した。使う機会はあるものの、使いこなせていない現状があるので上手く使えるようになりたい。