我有一个F#函数,如下所示:
open System.IO
open Microsoft.FSharp.Control.CommonExtensions
let rec copyData (ins:Stream) (outs:Stream) = async {
let! bytes = ins.AsyncRead(1)
do! outs.AsyncWrite(bytes)
return! moveData ins outs
}
当ins
流到达结尾时,它会抛出AtEndOfStream
异常。所以我必须在调用函数中捕获它。如何通过检测流当前结束来阻止此异常?
答案 0 :(得分:7)
您在此处使用的AsyncRead
重载会尝试准确读取您指定的字节数(如果它到达末尾则会失败,因为它无法读取指定的字节数)。
或者,您可以使用带缓冲区的重载并返回读取的字节数:
let rec copyData (ins:Stream) (outs:Stream) = async {
let buffer = Array.zeroCreate 1024
let! bytes = ins.AsyncRead(buffer)
if bytes > 0 then
do! outs.AsyncWrite(buffer, 0, bytes)
return! moveData ins outs
}
此重载不会在流的末尾抛出异常,而是返回0(并且它不会将任何内容写入缓冲区)。因此,您只需检查读取的字节数是否大于0,否则停止。
如果在调用copyData
之前已经关闭了流,那么您需要检查CanRead
或处理异常,但如果在调用AsyncRead
之前流已打开,那么您'我只会回来0。
答案 1 :(得分:1)
只需检查CanRead
属性,如下所示:
let rec copyData (ins:Stream) (outs:Stream) = async {
if ins.CanRead then
let! bytes = ins.AsyncRead(1)
do! outs.AsyncWrite(bytes)
return! moveData ins outs
}