Skip to content

Instantly share code, notes, and snippets.

@eulerfx
Created November 18, 2013 01:20
Show Gist options
  • Select an option

  • Save eulerfx/7520873 to your computer and use it in GitHub Desktop.

Select an option

Save eulerfx/7520873 to your computer and use it in GitHub Desktop.
To be used for transduction from sequences of arbitrary objects to byte streams.
module SeqStream
/// Reads a specified number of values from an enumeration into a buffer array.
let fillBuffer (enum:System.Collections.Generic.IEnumerator<_>) (buffer:_ array) offset count =
let mutable read = 0
while enum.MoveNext() && read < count do
buffer.[read + offset] <- enum.Current
read <- read + 1
read
/// A read-only stream which wraps an enumerator of a byte sequence.
type ByteEnumeratorStream (enumerator:System.Collections.Generic.IEnumerator<byte>) =
inherit System.IO.Stream()
let mutable position = 0L
override __.Read(buffer,offset,count) =
let read = fillBuffer enumerator buffer offset count
position <- position + (read |> int64)
read
override __.CanRead = true
override __.CanSeek = false
override __.CanWrite = false
override __.Flush() = ()
override __.Dispose(disposing) = enumerator.Dispose()
override __.Length = 0L
override __.Position with get () = position and set value = failwith "Can't set position!"
override __.Seek(offset, origin) = failwith "Can't seek!"
override __.Write(bugger,offset,count) = failwith "Can't write to read-only stream!"
override __.SetLength(value) = failwith "Can't set length!"
/// Wraps the specified sequence of byte rows in a Stream.
let ofByteRows rows =
let flatRows = rows |> Seq.concat
new ByteEnumeratorStream(flatRows.GetEnumerator())
let sw = System.Diagnostics.Stopwatch.StartNew()
let n = 50000
let bufferSize = 4096
let lines = Seq.init n (sprintf "line%i\r\n")
let rows = lines |> Seq.map (System.Text.Encoding.UTF8.GetBytes)
let stream = rows |> SeqStream.ofByteRows
use fs = System.IO.File.OpenWrite(@"c:\users\eulerfx\desktop\test.txt")
stream.CopyTo(fs, bufferSize)
sw.Stop()
printfn "wrote %i rows in %g seconds" n (sw.Elapsed.TotalSeconds)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment