ディレクトリとファイルの操作
Ruby にはDir、File、FileUtilsというディレクトリやファイルを操作する組み込みライブラリが用意されています。ここでは、その使い方を紹介します。なお、FileUtilsを利用する場合は、Ruby on Railsでは明示的なrequireは必要としませんが、Rubyではrequireが必要となります。
1-1.文字コード変換
Ruby on Railsと外部OSとのやり取りをする場合は、文字コードに注意しなければなりません。Ruby on Railsの世界ではUTF-8が使用されていますか゛、外部では異なるコード体系で動作していることが多くあります。そのため文字コード変換のライブラリが標準で用意されています。
(1) Kconv
require 'kconv'filenames = Dir.glob('*') # 全てのファイル名をシフトJISコードで取得
filenames.each do |f|
p "****"
p f # ShiftJISのまま表示
p f.kconv(Kconv::UTF8, Kconv::SJIS) # ShiftJIS から UTF-8 に変換し表示
end
上記の例としてファイル名が”あいうえお.txt”であるとき
f => \202\240 \202\242 \202\244 \202\246 \202\250.txt
f.kconv => \343\201\202 \343\201\204 \343\201\206 \343\201\210 \343\201\212.txt
となります。
16進表現では
f => x82A0 x82A2 x82A4 x82A6 x82A8.txt
f.kconv => xE38182 xE38184 xE38186 xE38188 xE3818A.txt
です。
Kconvを利用するときは文字コードは次の定数で指定します。
定数 | 文字コード |
---|---|
JIS | ISO-2022-JP |
EUC | EUC-JP |
SJIS | Shift_JIS |
BINARY | バイナリ |
ASCII | ASCII |
UTF8 | UTF-8 |
UTF16 | UTF-16 |
1-2.バックスラッシュ記法
プログラム内部では”あ い う え お”を”\202\240 \202\242 \202\244 \202\246 \202\250”のように文字そのものではなくコードで表現する場合があります。この表現方法の一つにバックスラッシュ記法があります。
バックスラッシュ記法 | 意味 |
---|---|
\t | タブ(0x09) |
\n | 改行(0x0a) |
\r | キャリッジリターン(0x0d) |
\f | 改ページ(0x0c) |
\b | バックスペース (0x08) |
\a | ベル (0x07) |
\e | エスケープ (0x1b) |
\s | 空白 (0x20) |
\nnn | 8 進数表記 (n は 0-7) |
\xnn | 16 進数表記 (n は 0-9,a-f) |
\cx | \C-xコントロール文字 (x は ASCII 文字) |
\M-x | メタ x (c | 0x80) |
\M-\C-x | メタ コントロール x |
\x | 文字 x そのもの |
1-3.カレントディレクトリ
プログラムを起動したときカレントディレクトリは実行しているプロジェクトのディリクトリにあり、Ruby on RailsではRAILS_ROOTにパスが入っています。
1-4.プロジェクトの生成
(1) プロジェクトAppli022を生成する
(2) 日本語環境の設定
(3) データベースの作成
1-5.ディレクトリ操作のプログラム作成
(1) コントローラの生成
NetBeansで[生成..]を選択します。
ジェネータ(G): controller
名前(N): commands
ビュー(V): index
exists app/controllers/
exists app/helpers/
create app/views/commands
exists test/functional/
create test/unit/helpers/
create app/controllers/commands_controller.rb
create test/functional/commands_controller_test.rb
create app/helpers/commands_helper.rb
create test/unit/helpers/commands_helper_test.rb
create app/views/commands/index.html.erb
(2) コントローラの編集
Ajaxを利用し、ファイル操作の結果を同一画面に表示させながら進行するプログラムとしましょう。
class CommandsController < ApplicationController
def index
enddef operate_dir
filenames = Dir.glob('*') # 全てのファイル名を取得
@result="<br>" + File::expand_path('.') + ">dir <br>"
filenames.each do |f|
fn = f.kconv(Kconv::UTF8, Kconv::SJIS) # ShiftJIS から UTF-8 に変換し表示
@result = @result + fn + "<br>"
end
enddef operate_chdir
Dir::chdir(@strarray[1]) # カレントディレクトリの変更
@result="<br>" + File::expand_path('.') + ">chdir #{@strarray[1]} <br>"
enddef operate_mkdir
Dir::mkdir(@strarray[1]) unless File::exist?(@strarray[1]) # ディレクトリの作成
@result="<br>" + File::expand_path('.') + ">mkdir #{@strarray[1]} <br>"
enddef operate_rmdir
Dir::delete(@strarray[1]) # ディレクトリの削除(但し空であること)
@result="<br>" + File::expand_path('.') + ">rmdir #{@strarray[1]} <br>"
enddef operate_rename
FileUtils::mv(@strarray[1], @strarray[2]) # ファイル名やディレクトリ名の変更
@result="<br>" + File::expand_path('.') + ">rename #{@strarray[1]} #{@strarray[2]} <br>"
enddef operate
str=params[:commandarea][:commandline]
@strarray=str.split("\040", 3) # 最初の空白で文字列を分割し配列に格納
case @strarray[0]
def operate
when "dir"
operate_dir
when "chdir"
operate_chdir
when "mkdir"
operate_mkdir
when "rmdir"
operate_rmdir
when "rename"
operate_rename
else
@result="#{@strarray[0]} <br> command error <br>"
end
render :partial => "resultarea"
endend
(3) レイアウトファイルの作成
Ajaxを利用するため、基本的なレイアウトファイルを作成します。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>Appli022: <%= controller.action_name %></title>
<%= javascript_include_tag :defaults %>
</head>
<body><%= yield %></body>
</html>
ここでRuby on Railsではjavascript_include_tag :defaultsと書いていますが、これは次のように展開されます。
<script src="/javascripts/prototype.js" type="text/javascript"></script>
<script src="/javascripts/effects.js" type="text/javascript"><
:position => "top",
:url => {:action => "operate"} do -%>
Command: <%= text_field :commandarea, :commandline, :size => 80 %><% end -%>
<br/>
<div id="resultarea"></div>
<%= "#{@result}" %>
1-6.動作確認
(1) 実装されたコマンドの種類
Command | 内容 |
---|---|
dir | カレントディレクトリ直下のディレクトリ名およびファイメ名の取得 |
chdir | カレントディレクトリの変更 | <
mkdir | ディレクトリの新規作成 |
rmdir | デイレクトリの削除(但しディレクトリ直下は空であること) |
rename | ディレクトリ名の変更 |
1-7.ファイル操作のプログラム作成
(1) ディレクトリの操作プログラムの機能追加
class CommandsController < ApplicationController
def index
enddef operate_dir
filenames = Dir.glob('*') # 全てのファイル名を取得
@result="<br>" + File::expand_path('.') + ">dir <br>"
filenames.each do |f|
fn = f.kconv(Kconv::UTF8, Kconv::SJIS) # ShiftJIS から UTF-8 に変換し表示
@result = @result + fn + "<br>"
end
enddef operate_chdir
Dir::chdir(@strarray[1]) # カレントディレクトリの変更
@result="<br>" + File::expand_path('.') + ">chdir #{@strarray[1]} <br>"
enddef operate_mkdir
Dir::mkdir(@strarray[1]) unless File::exist?(@strarray[1]) # ディレクトリの作成
@result="<br>" + File::expand_path('.') + ">mkdir #{@strarray[1]} <br>"
enddef operate_rmdir
Dir::delete(@strarray[1]) # ディレクトリの削除(但し空であること)
@result="<br>" + File::expand_path('.') + ">rmdir #{@strarray[1]} <br>"
enddef operate_rename
FileUtils::mv(@strarray[1], @strarray[2]) # ファイル名やディレクトリ名の変更
@result="<br>" + File::expand_path('.') + ">rename #{@strarray[1]} #{@strarray[2]} <br>"
enddef operate_copy
FileUtils::cp(@strarray[1], @strarray[2]) # ファイルのコピー
@result="<br>" + File::expand_path('.') + ">copy #{@strarray[1]} #{@strarray[2]} <br>"
enddef operate_read
@result="<br>" + File::expand_path('.') + ">read #{@strarray[1]} <br>"
File::open(@strarray[1], "r") do |f| # ファイルの読み込み
while str=f.gets
@result += str + "<br>"
end
end
enddef operate_clearlog
@result="<br>" + File::expand_path('.') + ">clearlog <br>"
File::open(RAILS_ROOT + "/appli022_log.txt", "w+") do |f| # Logファイルの初期化
f.print "appli022_log.txt \n"
end
enddef operate_printlog
@result="<br>" + File::expand_path('.') + ">printlog <br>"
@result += "Begin VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV <br>"
File::open(RAILS_ROOT + "/appli022_log.txt", "r") do |f| # Logファイルの読み込み
while str=f.gets
@result += str + "<br>"
end
end
@result += "End VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV <br>"
enddef operate
str=params[:commandarea][:commandline]
@strarray=str.split("\040", 3) # 最初の空白で文字列を分割し配列に格納
case @strarray[0]
when "dir"
operate_dir
when "chdir"
operate_chdir
when "mkdir"
operate_mkdir
when "rmdir"
operate_rmdir
when "rename"
operate_rename
when "copy"
operate_copy
when "read"
operate_read
when "clearlog"
operate_clearlog
when "printlog"
operate_printlog
else
@result="#{@strarray[0]} <br> command error <br>"
end
File::open(RAILS_ROOT + "/appli022_log.txt", "a+") do |f| # Logファイルの追記型オープン
f.print @result, "\n"
end
render :partial => "resultarea"
endend
1-8.動作確認
(1) 新たに実装されたコマンドの種類
Command | 内容 |
---|---|
rename | ファイル名の変更 |
copy | ファイルのコピー (ファイル名) → (ファイル名) (ファイル名) → (フォルダ名) |
read | テキストファイルの読み込み |
clearlog | ログファイルの初期化 |
printlog | ログのプリントアウト |