Search code examples
vb.netnewlinestreamreadermemorystream

Reading two lines from StreamReader VB.Net


I have a problem reading two lines from a stream reader. I want to read the first line and then proceed to the next one. Here's my code:

Public Function Read()
    Dim a As New MemoryStream(ASCII.GetBytes("[ID] " & vbCrLf & " salut" & vbCrLf))

    Debug.Print(client.ReadLine(a))
    Debug.Print(client.ReadLine(a))
End Function    


Public Function ReadLine(ByVal Data As MemoryStream)
    Dim sr As New StreamReader(Data)
    Return sr.ReadLine
End Function

The output is:

[ID]

One line. I checked the stream in debug mod and I've seen that the position was 15 after the first ReadLine call. So I have to move the "pointer" after the first VbCrLf(that's all the way to the end). But I don't think that's the proper way of doing it. Where am I wrong? I even passed the stream by value so it should've worked.

     EDIT
   I made some checks and it seems that and only when passing a stream the position moves to the end. I created a stream reader in the same Read function and passed as parameter the a memory stream. It worked. I don't know why this happen. I'm still looking for an answear.


Solution

  • It is not clear what you are really trying to do, but you are not really trying to read two lines from [a] StreamReader, you are trying to read one line at a time from two different streamreaders using the same data source/buffer.

    Dim buff = Encoding.ASCII.GetBytes("[ID] " & vbCrLf & " salut" & vbCrLf)
    
    Using ms As New MemoryStream(buff)
        Using sr As New StreamReader(ms)
            Console.WriteLine(sr.ReadLine())
            Console.WriteLine("memstream poition: " & ms.Position)
            Console.WriteLine(sr.ReadLine())
            Console.WriteLine("memstream poition: " & ms.Position)
            Console.WriteLine(sr.ReadLine())
        End Using
    End Using
    

    If you set a breakpoint on the first sr.ReadLine(), you'll see that the MemoryStream position has changed. If you mouse over the srvariable, you'll see why:

    enter image description here

    Streamreader has a buffer, 1024 bytes by default. You can compare that buffer to the one created in code and see they are the same. There is also a StreamReader overload which allows you to specify the size:

    Public Sub New(stream As System.IO.Stream, 
                    encoding As System.Text.Encoding,
                    detectEncodingFromByteOrderMarks As Boolean, 
                    bufferSize As Integer)
    

    Trying to read from a single data stream with different (new) StreamReaders wont work because the previous one will have already consumed some of the data. You should be able to read many thousands of lines into an array or list which your code can use as a line-buffer.