プログラミング言語 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