書き込む文字列をバッファにコピーするのが基本的なアイデアです。バッファに十分な空きが無く途中でバッファを空にする必要がある場合とそうでなく文字列全てをバッファに直接書き込める場合とを考える必要があります。解答例を以下に示します。
open Unix;;
let output_string chan s =
let avail = Bytes.length chan.out_buffer - chan.out_pos in
if Bytes.length s <= avail then begin
Bytes.blit s 0 chan.out_buffer chan.out_pos (Bytes.length s);
chan.out_pos <- chan.out_pos + Bytes.length s
end
else if chan.out_pos = 0 then begin
ignore (write chan.out_fd s 0 (Bytes.length s))
end
else begin
Bytes.blit s 0 chan.out_buffer chan.out_pos avail;
let out_buffer_size = Bytes.length chan.out_buffer in
ignore (write chan.out_fd chan.out_buffer 0 out_buffer_size);
let remaining = Bytes.length s - avail in
if remaining < out_buffer_size then begin
Bytes.blit s avail chan.out_buffer 0 remaining;
chan.out_pos <- remaining
end else begin
ignore (write chan.out_fd s avail remaining);
chan.out_pos <- 0
end
end;;
let ex2 () =
if Array.length Sys.argv < 3 then begin
prerr_string "Usage: test <sources> <dest>";
exit 2;
end;
let fdin = open_in Sys.argv.(1) in
let fdout = open_out Sys.argv.(2) in
prerr_endline "copying";
try while true do output_char fdout (input_char fdin) done
with End_of_file ->
prerr_endline "Done";
output_string fdout "The end.\n";
prerr_endline "Closing";
close_out fdout;;
handle_unix_error ex2 ();;
./ex2.byte ex2.ml ex2.out
(cat ex2.ml; echo "C'est la fin.") | diff --brief - ex2.out
rm ex2.out
* * *