open Unix;; (* program constants *) let slice_size = ref 1024;; let buffer_size = 4096 ;; let buffer = String.create buffer_size (* name generation function for output files *) let slicename name index = Printf.sprintf "%s-%d" name index;; let rec copy_data fd_in fd_out tocopy = if tocopy > 0 then let len = Unix.read fd_in buffer 0 (min tocopy buffer_size) in if len > 0 then begin ignore (Unix.write fd_out buffer 0 len); copy_data fd_in fd_out (tocopy - len) end else tocopy else 0 (* do the job *) let split file size = Printf.fprintf Pervasives.stderr "file=%s size=%d" file size; prerr_newline(); let fd_in = Unix.openfile file [ O_RDONLY ] 0 in let rec copy_slices slice = let fd_out = Unix.openfile (slicename file slice) [O_WRONLY;O_CREAT;O_TRUNC] 0o666 in let left = copy_data fd_in fd_out size in Unix.close fd_out; if left = 0 then copy_slices (slice + 1) in copy_slices 0; Unix.close fd_in (* errors and arguments handling functions*) let errors = ref false;; let process_file file = try split file !slice_size with Unix_error (e,b,c) -> errors := true; prerr_string (Sys.argv.(0)^": " ^c^ ": " ^(error_message e)); prerr_newline ();; let set_size nb = if nb > 0 then slice_size := nb else raise (Arg.Bad "Size must be strictly positive");; let usage = "Usage: " ^ Sys.argv.(0) ^ " [ option ] filename";; (* main function *) let mon_split () = Arg.parse [ ("-b", Arg.Int set_size, "byte number") ] process_file usage; if !errors then exit 1;; handle_unix_error mon_split();; |