(F#)从CryptoStream读取所有字节的最流畅的方法

Sea*_*n U 2 f# stream

我正在研究使用AesCryptoServiceProvider解密二进制数据的过程.对于最后一步,检索解密数据并将其作为字节数组返回,我目前正在使用以下实现:

let rec streamBytes (s : CryptoStream) (b : int) = seq {
    if b >= 0 then
        yield byte b
        yield! streamBytes s (s.ReadByte()) }
streamBytes cryptoStream (cryptoStream.ReadByte())
|> Seq.toArray
Run Code Online (Sandbox Code Playgroud)

它有效,但它对我来说并不"正确".将CryptoStream.ReadByte()的结果作为参数传递给streamBytes(),然后检查该递归调用中的值似乎有点Rube Goldberg-y.有更好的方法吗?

des*_*sco 13

逐字节排出流将非常慢.

如果你有.NET 4.0,那么最直接的方法是:

open System.IO

let readAllBytes (s : Stream) = 
    let ms = new MemoryStream()
    s.CopyTo(ms)
    ms.ToArray()
Run Code Online (Sandbox Code Playgroud)

否则你需要手动重现CopyTo功能

let readAllBytes (s : Stream) =
    let ms = new MemoryStream()
    let buf = Array.zeroCreate 8192
    let rec impl () = 
        let read = s.Read(buf, 0, buf.Length) 
        if read > 0 then 
            ms.Write(buf, 0, read)
            impl ()
    impl ()
Run Code Online (Sandbox Code Playgroud)

  • @SeanU:虽然我同意应该处理_anything_实现`IDisposable`,但值得一提的是`MemoryStream`只实现`IDisposable`,因为`Stream`就是这样(即它的`Dispose`实现是一个无操作并且只存在,因为它在基类中是抽象的). (4认同)