1

我有一个 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异常。所以我必须在调用函数中捕获它。如何通过检测流当前处于末尾来防止此异常?

4

2 回答 2

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。

于 2013-01-07T11:32:25.620 回答
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
}
于 2013-01-07T02:21:43.797 回答