(F #) Самый плавный способ чтения всех байтов из CryptoStream - PullRequest
2 голосов
/ 24 мая 2011

Я работаю над процедурой дешифрования двоичных данных с помощью 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. Есть ли лучший способ сделать это?

Ответы [ 2 ]

13 голосов
/ 24 мая 2011

Слив потока байта за байтом будет очень медленным.

если у вас есть .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, 0, buf.Length) 
        if read > 0 then 
            ms.Write(buf, 0, read)
            impl ()
    impl ()
1 голос
/ 24 мая 2011

Есть ли причина не использовать Read вместо ReadBytes? Кажется, что это было бы намного более прямым. В противном случае ваше решение не выглядит для меня слишком плохо - дизайн API довольно ограничен, так как вам нужно использовать возвращаемое значение ReadByte, чтобы определить, следует ли разорвать ваш цикл и решить, какое значение вывести. Вот одна альтернативная реализация:

[| let currentByte = ref 0
   let moveNext() = 
       currentByte := cryptoStream.ReadByte()
       !currentByte >= 0
   while moveNext() do
       yield byte !currentByte |]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...