(* file.ml - Don Yang (uguu.org) 05/20/06 *) (* Copy file and attributes to destination, assumes dependent directories already exist. *) let buffer_size = 0x10000;; let rec copy_recurse infile outfile buffer size = if size = 0 then () else (let read_size = Unix.read infile buffer 0 (if size > buffer_size then buffer_size else size) in if (Unix.single_write outfile buffer 0 read_size) < read_size then failwith "IO error" else copy_recurse infile outfile buffer (size - read_size));; let copy_with_stat (src_file, src_stat) dst_file = let infile = Unix.openfile src_file [Unix.O_RDONLY] 0 in let outfile = Unix.openfile dst_file [Unix.O_CREAT; Unix.O_WRONLY] src_stat.Unix.st_perm in let buffer = String.create buffer_size in copy_recurse infile outfile buffer src_stat.Unix.st_size; Unix.close infile; Unix.close outfile;; let copy src_file dst_file = copy_with_stat (src_file, Unix.stat src_file) dst_file;; (* Compare two files, returns true if they are different *) let rec compare_recurse file1 file2 buffer1 buffer2 size = if size = 0 then false else let read_size1 = Unix.read file1 buffer1 0 buffer_size in let read_size2 = Unix.read file2 buffer2 0 buffer_size in if read_size1 <> read_size2 then true else if (String.sub buffer1 0 read_size1) <> (String.sub buffer2 0 read_size1) then true else compare_recurse file1 file2 buffer1 buffer2 (size - read_size1);; let compare_with_stat (f1, s1) (f2, s2) = if s1.Unix.st_size <> s2.Unix.st_size || s1.Unix.st_perm <> s2.Unix.st_perm then true else (let file1 = Unix.openfile f1 [Unix.O_RDONLY] 0 in let file2 = Unix.openfile f2 [Unix.O_RDONLY] 0 in let buffer1 = String.create buffer_size in let buffer2 = String.create buffer_size in let cmp = compare_recurse file1 file2 buffer1 buffer2 s1.Unix.st_size in Unix.close file1; Unix.close file2; cmp);; let compare file1 file2 = try let stat1 = Unix.stat file1 in let stat2 = Unix.stat file2 in compare_with_stat (file1, stat1) (file2, stat2) with Unix.Unix_error _ -> true;;