プログラミング言語 Standard ML 入門 (問題の解答例)
17.2 ディレクトリとファイルの操作
問 17.1
上記の ls 関数を改良し,各ファイルごとに, ファイルの種類(ディレクトリ,リンク,通常ファイル),ファイルのアクセス (読み出し可,書き込み可,実行可),最終更新年月日,ファイルサイズを以下の ような形式で表示するようにせよ.
- ls(); dlrwx file size last modified file name d-rwx 4096 Mar 19 10:50 examples --rw- 18666 Apr 8 09:39 ml.tex --rw- 257094 Mar 18 16:40 part1.tex --rw- 186111 Apr 16 10:58 part2.tex
先頭の dlrwx はそれぞれ,ディレクトリ,リンク,読み込み可,書き込み可, 実行可を表す.
解答例
fun ls () = let val d = F.openDir (F.getDir()) fun printRest () = case F.readDir d of NONE => F.closeDir d | SOME f => let val size = F.fileSize f val time = Date.toString (Date.fromTimeLocal (F.modTime f)) val modString = implode [if F.isDir f then #"d" else #"-", if F.isLink f then #"l" else #"-", if F.access (f, [F.A_READ]) then #"r" else #"-", if F.access (f, [F.A_WRITE]) then #"w" else #"-", if F.access (f, [F.A_EXEC]) then #"x" else #"-"] in (Format.printf "%10s%15d%30s%30s\n" [Format.S modString, Format.I size, Format.S time, Format.S f ]; printRest()) end in (Format.printf "%10s%15s%30s%30s\n" [Format.S "dlrwx", Format.S "file size", Format.S "last modified", Format.S "file name" ]; printRest() ) end
問 17.2
copy 関数が,ファイルおよびディレクトリの更新日付を保存する ように変更せよ.
解答例 copy関数にF.setTimeコマンドを追加すればよい。 変更例を以下に示す。
fun copy a b = if not (F.isDir a) then (copyFile a b; F.setTime (b,SOME (F.modTime a))) else let val d = F.openDir a fun copyDirStream d b = case F.readDir d of NONE => F.closeDir d | SOME item => let val from = P.concat (a,item) val to = P.concat (b,item) in (copy from to;copyDirStream d b) end in (F.mkDir b; copyDirStream d b; F.setTime (b,SOME (F.modTime a))) end