将字符串转换为流

Dan*_*roa 4 f# .net-core

我正在尝试将字符串转换为字节流,以便我可以读取所述流.所以我正在做的是将字符串转换为char数组并将每个char/byte写入MemoryStream,然后将其包装在BinaryReader中

我尝试实现它的方式是这样的:

let readData (data:string) = 
    let ms = new MemoryStream()
    let bw = new BinaryWriter(ms)
    data.ToCharArray() |> Array.iter (fun x -> bw.Write((byte)x))
    let br = new BinaryReader(bw.BaseStream)
    readStream 0 br
Run Code Online (Sandbox Code Playgroud)

我后来试着这样读

let rec readStream c (br:BinaryReader) =
    let bytes = br.ReadBytes 16
    printfn "Size read is: %i" bytes.Length
Run Code Online (Sandbox Code Playgroud)

但我的结果总是读取0字节,我已经验证字符串显然不是0字节.我试过在MemoryStream上调用Flush.

我错过了一些基本的东西,还是另一种更明显的方法呢?

Fyo*_*kin 9

这是一种非常低效的制作方法MemoryStream.特别是对于这种应用程序,它有一个带字节数组的构造函数:

let bytes = System.Text.Encoding.UTF8.GetBytes data
let stream = MemoryStream( bytes )
Run Code Online (Sandbox Code Playgroud)

但即使可能是一种矫枉过正.您还没有描述您的最终目标,但是从您的代码中看起来您只想将字符串转换为字节数组.如果这是真的,你只需要Encoding.GetBytes:

let readData (data:string) = System.Text.Encoding.UTF8.GetBytes data
Run Code Online (Sandbox Code Playgroud)

.

在铸造

还要注意,当你这样做时(byte)x,你显然希望这是一个"转换为字节"操作,就像在C#中一样,但事实并非如此.F#中的"强制转换"操作表达方式不同(使用运算符:>:?>),它只能用于子/超类型(即继承的类和接口).不适用于原语.在F#中没有投射基元类型的东西.

你实际在做的是调用一个名为的函数byte.因此在那里不需要括号,F#中的函数参数用空格指定,即byte x.

这个函数确实将char转换为一个字节,但是只需要取char的第一个字节(字符是双字节的东西,你知道吗?)并扔掉第二个字节.当你的char是ASCII(第二个字节为零)时,这种方法很好,但是当它不是时会丢失数据.尝试转换为byte然后返回char:

let x = 'a'
let y = char (byte x)
> val y : char = 'a'  // This worked

let x = '?'
let y = char (byte x)
> val y : char = '\019'  // Oops
Run Code Online (Sandbox Code Playgroud)