Search code examples
vb.netunicodebinaryasciiuint16

Error reading UInt16 from BinaryReader


Why does this work

Dim mem As New MemoryStream()
Dim bin As New BinaryWriter(mem)
bin.Write(CUShort(1000))
Dim read As New BinaryReader(New MemoryStream(mem.ToArray))
MsgBox(read.ReadInt16)

The message box give me 1000 which is right. Then I try to use this

Dim mem As New MemoryStream()
Dim bin As New BinaryWriter(mem)
bin.Write(CUShort(1000))
Dim s As String = ASCII.GetString(mem.ToArray)
Dim read As New BinaryReader(New MemoryStream(ASCII.GetBytes(s)))
MsgBox(read.ReadInt16)

It gives me 831 which is incorrect. Now I try it with Unicode encoding. It works. But I want to use ASCII. Why is this, and what am I doing wrong?


Solution

  • What you experience happens because of the way the .NET Runtime stores strings in memory, and because different encodings have a different set of characters.

    A (U)Short is represented in memory by two bytes. When you call ASCII.GetString() the byte array is interpreted as coming from an ASCII string and is therefore converted into a UTF-16 string. This conversion is performed because UTF-16 is the encoding that all strings are stored as in memory by the .NET runtime.

    Encoding.Unicode however is the same as UTF-16, so (at this point) no extra conversion is needed to store the string in memory. The byte array is just copied and marked as a string, thus you get the very same bytes and the same UShort.

    This fiddle illustrates what I'm talking about: https://dotnetfiddle.net/p4EKn9