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または処理する必要がありますが、を呼び出す前にストリームが開いている場合は、AsyncRead0 が返されます。

于 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 に答える