Juliaのファイル操作系の機能を使ってみる。
cd, pwd, mv, cp, touchといった馴染みの名前が関数名になっているので、非常に覚えやすい。
バージョンは0.3.4を使用。ソースコードを見るとまだ定まってない感が醸しだされているので、バージョンが変わるといろいろ変更は出そう。
機能の一覧は下記参照
http://julia.readthedocs.org/en/latest/stdlib/file/
writeで書き込める。戻り値は書き込んだバイト数。
# openしてブロック内で書き込み open( "a.txt", "w" ) do fp write( fp, "日本語を書き込んでみる\n" ) end # 追記 open( "a.txt", "a" ) do fp write( fp, "追記してみる\n" ) println( fp, "printlnしても良い" ) end
上記のようにブロック内で書いた場合、closeは自動で行われる。具体的には下記のような処理が呼ばれている。
function open(f::Function, args...) io = open(args...) try f(io) finally close(io) end end
ブロックを使わずに下記のように書くこともできる。
fp = open("ファイル名") write( fp, "書き込み" ) close( fp )
このへんはRubyの書き方に近いイメージ。
尚、STDOUTを指定してwriteすると、標準出力に出力される。
write( STDOUT, "標準出力に出力する" ) #=> 標準出力に出力する27
eachlineで1行ずつ読み込んでみる。
open( "a.txt", "r" ) do fp for line in eachline( fp ) print( line ) end end
readallで全文字を読み込む。
str = open( "a.txt", "r" ) do fp readall( fp ) end
各行を配列として読み込む。
lines = open( "a.txt", "r" ) do fp readlines( fp ) end
ちなみに0.3.4時点だとJuliaのreadlineは readline(s::IO) = readuntil(s, '\n') とされていて、うちの環境では\rは改行として認識されない。改行コードの扱いはOSごとで変わるんかな。(未調査)
文字コードは基本、UTF-8。sjisとかeucのファイルを読みたい時は……どうするんだろう。ざっとdocument見たけどそれっぽいものは見当たらなかった。iconv噛ませてどうこうとかするんかな。
openの引数に関数を渡すこともできる。
# 処理を関数で書いておいて、openに渡す場合 f( fp ) = for line in eachline( fp ) print(line) end open( f, "a.txt" )
この場合も自動でcloseは行われる。
GZipパッケージを利用。
読み込み
# 準備 Pkg.add("GZip") import GZip # ブロックで処理を渡す GZip.open( "foo.gz" ) do fp for line in eachline( fp ) print( line ) end end # 関数で処理を渡す f( fp ) = for line in eachline( fp ) print(line) end open( f, "foo.gz" )
書き込み
GZip.open( "tmp.gz", "w" ) do fp write( fp, "1行目\n" ) write( fp, "2行目\n" ) end
cp(コピー元, コピー先) でコピー可能。戻り値はFile型。
# コピー用のファイルを作成しておく touch("a.txt") # コピー _file = cp( "a.txt", "b.txt" ) #=> > File("b.txt",false,-1)
File型は、help( "File" ) で見てみると、open, cp, mvなどひと通りのことは出来る様子。
mv(移動元, 移動先) で移動可能。戻り値はNothing。
mv( "a.txt", "c.txt" )
rmで削除
# ファイルの削除 rm("a.txt") # ディレクトリも消せるけど空じゃないとエラーになる rm("dir1") #=> ERROR: rmdir: ディレクトリは空ではありません # recursiveをtrueに設定すれば空じゃなくても消せる rm("dir1", recursive=true)
mkdirで作れる。
mkdir( "foo" ) # 既に存在する場合は例外 mkdir( "foo" ) #=> ERROR: mkdir: ファイルが存在します # mkdirは再帰的には掘れない mkdir( "foo/bar/baz" ) #=> ERROR: mkdir: そのようなファイルやディレクトリはありません # 2階層以上掘りたい場合はmkpathを使う。 mkpath( "foo/bar/baz" )
カレントディレクトリの下を一覧で出す。readdirを使う。
readdir( "." ) # filterとisfileでファイルだけを抽出する filter(f -> isfile(f), readdir(".")) # isdirでディレクトリだけを抽出する filter(f -> isdir(f), readdir("."))
ディレクトリを再帰的に見る(0.3.4の段階では末尾再帰の最適化はないらしい)
f(dir) = for child = readdir(dir) child = joinpath(dir, child) println( abspath( child ) ) isdir( child ) && f( child ) end f(".")
ファイルサイズはfilesizeで取れる。
filesize( "a.txt" )
作成日や更新日はctime, mtimeで取れる。
ctime( "a.txt" ) #=> 1.420523529135508e9 mtime( "a.txt" ) #=> 1.4205235290955074e9
floatで返ってくる。int( ctime( "a.txt" ) ) するとunix timestampになる。
download( "http://www.yahoo.co.jp/", "foo.txt" )
ちなみにこれ、UNIX系のOSだと下記のようにwgetとかcurlとかが入ってたら叩くというだけの処理をしてる。
if downloadcmd == :wget run(`wget -O $filename $url`) elseif downloadcmd == :curl run(`curl -o $filename -L $url`) elseif downloadcmd == :fetch run(`fetch -f $filename $url`) else error("no download agent available; install curl, wget, or fetch") end
Windows系だと別途何かを叩いてるっぽい。