我認爲你的方法看起來不錯。唯一的問題是,Stream
是一個相對複雜的類,有相當多的成員,你可能不想實現其中的大部分 - 如果你想將它傳遞給一些使用一些額外成員的代碼,你會需要使實現更復雜。總之,只實現Read
一個簡單的流可以是這樣的:
type SeqStream<'a>(sequence:seq<'a>, formatter:'a -> byte[]) =
inherit Stream()
// Keeps bytes that were read previously, but were not used
let temp = ResizeArray<_>()
// Enumerator for reading data from the sequence
let en = sequence.GetEnumerator()
override x.Read(buffer, offset, size) =
// Read next element and add it to temp until we have enough
// data or until we reach the end of the sequence
while temp.Count < size && en.MoveNext() do
temp.AddRange(formatter(en.Current))
// Copy data to the output & return count (may be less then
// required (at the end of the sequence)
let ret = min size temp.Count
temp.CopyTo(0, buffer, offset, ret)
temp.RemoveRange(0, ret)
ret
override x.Seek(offset, dir) = invalidOp "Seek"
override x.Flush() = invalidOp "Flush"
override x.SetLength(l) = invalidOp "SetLength"
override x.Length = invalidOp "Length"
override x.Position
with get() = invalidOp "Position"
and set(p) = invalidOp "Position"
override x.Write(buffer, offset, size) = invalidOp "Write"
override x.CanWrite = false
override x.CanSeek = false
override x.CanRead = true
注意,我增加了一個額外的參數 - 對一般類型的值轉換爲字節數組的功能。一般來說,很難將任何東西轉換爲字節(可以使用一些序列化),所以這可能更容易。例如,對於整數,您可以編寫:
let stream = new SeqStream<_>([ 1 .. 5 ], System.BitConverter.GetBytes)