Resolved What buffer is too small?

realolman

Member
Joined
Jan 2, 2017
Messages
15
Programming Experience
10+
I get this error when trying to read from a file that I have written using the second block of code (Sub WriteToFile()) :
An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll

Additional information: The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'.


I can't figure out what is happening.. What I am trying to do is : write a list of doubles and read a list of doubles ... and I don't know why I am getting the error in the line 17... What output char buffer?


VB.NET:
  Private Sub btnReadFile_Click_1(sender As Object, e As EventArgs) Handles btnReadFile.Click
        Dim strSeconds As String
        txtReadFile.Text = ""
        txtFileName.Text = ""
        My.Computer.FileSystem.CurrentDirectory = "C:\Users\Wayne\Desktop\furnace monitoring files"
        OpenFileDialog1.Title = "Please Select File"
        OpenFileDialog1.Filter = "fmf|*.fmf"
        OpenFileDialog1.FileName = ""
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            txtFileName.Text = OpenFileDialog1.SafeFileName
            My.Computer.FileSystem.CurrentDirectory = "C:\Users\Wayne\Desktop\furnace monitoring files"
            Dim fsr As New FileStream(OpenFileDialog1.FileName, FileMode.Open, FileAccess.Read)
            Dim breader As New BinaryReader(fsr)
            CC = 3
            'Try
            'Catch ex As IOException
           Do While breader.PeekChar > -1
                readFileSeconds(CC) = breader.ReadDouble
                txtReadFile.Text = txtReadFile.Text & vbCrLf & strSeconds & vbCrLf
                readFileSeconds(CC) = CDbl(strSeconds)
                CC = CC + 1
            Loop
            'End Try
            breader.Close()
            breader.Dispose()
            fsr.Close()
            fsr.Dispose()
        End If
    End Sub

    Sub WriteToFile()
        Dim myDate As String
        Dim fileName As String
        btnSaveToFile.Enabled = False
        btnSaveToFile.Text = "saving to file"
        myDate = Now.ToString("ddMMMyy HH mm.ss")
        fileName = myDate & ".fmf"
        txtStartTime.Text = myDate
        My.Computer.FileSystem.CurrentDirectory = "C:\Users\Wayne\Desktop\furnace monitoring files"

        Dim fs As New FileStream(fileName, FileMode.Append, FileAccess.Write)
        Dim bwriter As New BinaryWriter(fs)
        For c = 3 To 12
            bwriter.Write(timeSeconds(c)) ' timing of event
            tbxWritten.Text = tbxWritten.Text & vbCrLf & timeSeconds(c)
        Next
        bwriter.Close()
        fs.Close()
        'LastState(CC) = intState
        btnSaveToFile.Enabled = True
        btnSaveToFile.Text = "save to file"

    End Sub
VB.NET:
What can I do to fix this ?

thank you Realolman
 
BinaryReader uses UTF8 encoding by default, with PeekChar you're forcing BR to try read one char using that encoding. Probably it encounters a value it thinks is a surrogate pair which won't fit as one char. Since your data is not character data you should not use PeekChar, instead you can use its BaseStream.Position and check against FileStream.Length.
 
Thank you for your reply... I saw something about UTF8 somewhere I was looking to try to solve this, but I didn't understand it .
I had used this code to read and write in another project and it worked fine.


VB.NET:
  Do While breader.PeekChar > -1

                strReadInputState = breader.ReadString()
                ReadMilli = breader.ReadUInt64
                dteReadTime = DateTime.FromFileTime(Long.Parse(ReadMilli))

I thought I could modify it to read /write just doubles ... apparently I thought wrong... I will try to use your suggestion and I thank you very much
You know... a person could lose his marbles doing this stuff :/)
Realolman
 
The thing with BinaryWriter/BinaryReader they are designed to enable writing/reading different typed data like a protocol, for example you write an integer, a double, a string - then you read back an integer, a double, a string. In the case of the string there is no need to peek because strings written by BW is length prefixed so that BR can read them back exactly that many chars. When writing a variable set of for example doubles you should know at the time of writing how many, so you can write that number first, then the set of doubles. When reading you can read the number first, then loop that many times to read the expected doubles. This pseudo example has the number 4 which means there are 4 doubles following:

4 1.1 2.2 3.3 4.4

VB.NET:
Dim count = BR.ReadInt32
For i = 1 To count
   Dim value = BR.ReadDouble
  
next
 
I think I am understanding that if I "write" exactly the number of doubles that I attempt to "read" ...that I don't have to check for the end of the file, and it will work correctly.
That is how I modified my program to work, and so far it works dandy.
 
Back
Top