问题描述
||
我正在研究使用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
它可以工作,但是对我来说感觉不“正确”。将CryptoStream.ReadByte()的结果作为参数传递给streamBytes(),然后在该递归调用中检查值是否似乎有点Rube Goldberg-y。有更好的方法吗?
解决方法
逐字节排空流将非常慢。
如果您拥有.NET 4.0,那么最直接的方法是:
open System.IO
let readAllBytes (s : Stream) =
let ms = new MemoryStream()
s.CopyTo(ms)
ms.ToArray()
否则您需要手动重现CopyTo功能
let readAllBytes (s : Stream) =
let ms = new MemoryStream()
let buf = Array.zeroCreate 8192
let rec impl () =
let read = s.Read(buf,buf.Length)
if read > 0 then
ms.Write(buf,read)
impl ()
impl ()
,是否有理由不使用Read
而不是ReadBytes
?似乎那将更加直接。否则,您的解决方案对我来说并不算太糟糕-API的设计非常有限,因为您需要使用返回值ReadByte
来确定是否中断循环并确定要输出的值。这是一种替代实现:
[| let currentByte = ref 0
let moveNext() =
currentByte := cryptoStream.ReadByte()
!currentByte >= 0
while moveNext() do
yield byte !currentByte |]